汇编语言调试常用方法
output:
.asciz "The value is %d\n"
该字符串在内存中占用17个字节:从gdb的测试中可知
(gdb) x/17cb &output
0x8049264 <output>: 84'T' ............... 0'\000'
在汇编语言中调用C语言的函数是,必须在调用之前将参数push进栈中,比如有一下例子:
#asm_printf.s 这是一个测试用汇编语言调用C函数库的例子
.section .data
output:
.asciz "The value is %d\n"
.section .text
.globl _start
_start:
nop
movl $100, %eax
pushl %eax
pushl $output
call printf
addl $8, %esp
movl $1, %eax
movl $0, %ebx
int $0x80
这段程序就是一个简单汇编调用C函数的例子
按照下面的命令编译该程序
as -gstable -o asm_printf.o asm_printf.s
ld -dynamic-linker /lib/ld-linux.so.2 -lc -o asm_printf asm_printf.o
说明:为了用gdb来调试该程序需要在编译时加入“-gstable”参数
printf 来源于glibc的动态链接库,所以需要链接进一个“运行时动态链接库”/lib/ld-linux.so.2
nop是为了解决一个gdb的bug
gdb ./asm_printf
break *_start+1 //说明:设置断点
run //运行
info register //查看寄存器的内容
x/17cb &output //实际上output是一个地址,该命令是查看output地址中所指的内容,在所有编译时期可以分配的空间,其地址是可以明确的,在该例子中output的地址是0x8049264,也就是字符串中'T'这个字符的地址。
x/x %esp //查看寄存器 esp的内容 x/d %esp ,十进制的方式查看
x/4cb $esp-8 //试验一下命令
为了让printf能使用必须先将参数push进栈中,先push 100 ,再push 0x8049264 ,一次4个字节,一共2次8个字节,每次push完之后,esp寄存器自动指向栈顶,liux中栈是从高地址向低地址扩展,每push一个字节,esp自动会减1,所以在调用完printf 之后,需要恢复到调用之前的状态,直接将esp+8,就可以了。
最后3条语句一般来讲就是系统调用,返回!
浙公网安备 33010602011771号