汇编语言调试常用方法

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条语句一般来讲就是系统调用,返回!

posted on 2011-08-03 16:30  莫等闲再读书  阅读(519)  评论(0)    收藏  举报

导航