汇编中常用的三种段为:
数据段,声明带有初始值的数据元素;
文本段,可执行程序声明指令码的地方;
BSS段,声明使用0或NULL值初始化的数据元素,常用作缓冲区。
BSS段中声明的数据是不包含在可执行程序中的,而数据段定义的数据必须在可执行文件中。
objdump 对目标代码文件进行一系列操作:
$objdump -d test.o #反汇编目标文件
编译时加入调试:
$as -gstabs -o test.o test.s
$ld -o test test.o
进行调试,设置断点:
break *label+offset
调试时:
显示所有寄存器值:
info registers
显示特定寄存器或程序变量的值:
print/d //十进制 例如,print/d $eax
print/t //二进制
print/x //十六进制
显示内存特定位置的值:
x /nyz // n表示显示的字段数,y表示输出格式(c表示字符,d表示10进制,x表示十六进制),z表示显示的字段长度(b表示字节,h表示半字,w表示字)
参数放入堆栈的顺序和printf函数获取它们的顺序是相反的。
GCC中使用AT&T汇编语法。
立即数前加 $ 符号。
寄存器前加 % 符号。
链接到C库函数的链接:
ld -dynamic-linker /lib/ld-linux.so.2 -o test -lc test.o
使用eax寄存器的32位 %eax, 16位 %ax, 8位 %al.
8个通用寄存器(EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP).
value:
.int 33
movl value, %eax #将value内的值传给eax寄存器
movl $value, %eax #将value地址值传给eax寄存器
movl %ebx, %edi #将ebx内的值传给edi
movl %ebx, (%edi) #将ebx内的值传给edi内的地址位置
movl %ebx, -4(%edi) #将ebx内的值传给edi内的地址位置之前4个字节的位置