1.编译与链接
方法一:使用as
#as -o test.o test.s
#ld -o test test.o
方法二:使用gcc
#gcc -o test test.s
gnu连接器查找_start标签以确定程序的开始,但gcc查找main标签,所以使用gcc要把 _start改为main
2.调试
#as -gstabs -o test.o test.s
#ld -o test test.o
3.定义数据
数据段
使用.data命令声明 标签+命令
.ascii 文本字符串
.asciz 以空字符结尾的文本字符串
.int 32位整数 .short 16位整数
.float 单精度浮点数 .double 双精度浮点数
.quad 8字节整数
例如:
.section .data
output:
.ascii "This is a string"
height:
.int 78
length:
.int 34,79,90
静态符号
equ命令用于把常量值设置为可以在文本段中使用的符号
例如:
.equ linux_sys_call ,0x80
使用静态数据要加$
movl $linux_sys_call ,%eax
BSS段
.comm 声明未初始化的数据的通用内存区域
.lcomm 声明未初始化的数据的本地通用内存区域(为不会从本地汇编代码之外进行访问的数据保留的)
例如:
.section .bss
.lcomm buffer ,1000
把 1000字节的内存区域赋值给buffer标签
一个程序本质上都是由 bss段、data段、text段三个组成的
在采用段式内存管理的架构中(比如intel的80x86系统),bss段(Block Started by Symbol segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域,一般在初始化时bss 段部分将会清零。bss段属于静态内存分配,即程序一开始就将其清零了。
比如,在C语言之类的程序编译完成之后,已初始化的全局变量保存在.data 段中,未初始化的全局变量保存在.bss 段中。
3.nop
空指令即空操作
4.cpuid
cpuid指令运行之后,分散在3个寄存器ebx,edx,ecx
(gdb) p/c $bx
$18 = 71 'G'
(gdb) p/c $bl
$19 = 71 'G'
(gdb) p/c $bh
$20 = 101 'e'
(gdb) p/c $cl
$21 = 110 'n'
(gdb) p/c $ch
$22 = 116 't'
(gdb) p/c $ecx
$23 = 110 'n'
(gdb) p/c $dh
$24 = 110 'n'
(gdb) p/c $dl
$25 = 105 'i'
5.linux系统调用
movl $1, %eax
movl $0, %ebx
int $0x80;从linux内核访问控制台显示,使用int生成软中断,linux内核提供
6.指针
.section .data
output:
.ascii "The processor Vendor ID is 'xxxxxxxxxxxx'\n"
.section .text
.globl _start
_start:
movl $0, %eax
cpuid
movl $output, %edi ;output标签的内存位置加载到edi寄存器中
movl %ebx, 28(%edi);ebx寄存器中的内容按照edi指针放到内存的指定位置。括号外的数字表示相对于output标签放置数据的位置,这个数字和edi寄存器中的地址相加
movl %edx, 32(%edi)
movl %ecx, 36(%edi)
The processor Vendor ID is 'GenuineIntel'
7.使用C库函数
printf
--《未完》--