一个简单程序的 gdb 反汇编 分析

《深入理解计算机》的第三章已经看了两遍了,一直都是在看书里的程序,一些内容都是第一次接触,也一直没有在真正的Linux上用过,今天写了下发现和书里的还是有些出入,下面是我自己的理解。

gdb除了反汇编外,还可以用于代码的调试。下面就简单记录下容易忘记的部分。

1.gcc -g -o code code.c   这里不要忘记-g

2.watchpoint的概念

   VC用惯了就是不好,在vc里ms没有这个概念,至少我没遇到过。在gdb中有一个watch命令,格式是watch + addr, 当内存中这个地址被写入新内容时程序就会中断。

3.查看内存内容的方法

  X/4b  &temp

  这个意思就是输出7个byte从temp所在地址开始的内存内容。

  比如我的temp = 0xfeff,那么会输出0xff 0xfe 0x00 0x00(小端地址法)

 

下面是自己花了点时间在Linux下写了一个简单的程序,并分析了下反汇编的代码,以及内存情况。

第一部分是c语言代码,编译时用gcc -o code code.c,没用-O2优化

 

第二部分是用gdb code的反汇编代码,';'后面是我自己的注释,关于前4句的原理可以看最下面的文章,对理解比较重要。

有疑问的部分:

0x080483d8 <main+49>:   add    $0x10,%esp:从这里往前看,似乎只有3次push操作,应该add 0xc,只是在这个程序中多add0x4也没关系。

0x080483ec <main+69>:   sub    $0x8,%esp: 这个好像没用到,好像也不是用于字节对齐,因为在它前面一次调用也是从这个值开始的。

 

在这里leave等价于:

mov %esp,%ebp;

pop %ebp

 

 

第三部分是内存变化的简单示意图:

 

-----------------------------------------------------------------------------------------------------------------------

下面来自于网上

C 代码:

int main(){
}

 

push %ebp
mov %esp,%ebp
sub $0x8,%esp//这句可以勉强理解,可能是为以后定义变量欲留位置,不知对否?
and $0xfffffff0,%esp//这里就不好理解了,为什么要把后面的4位全都置0???
mov $0x0, %eax
sub %eax,%esp
leave
ret

 

首先我觉得有必要把LEAVE替换一下,他等价于mov esp,ebp;pop ebp这两条指令.因此有如下的解释:

 

因此在执行了1之后的堆栈图是: ----> 这个ARG其实就是int main(int argc, char argv[]),其实这里还可以跟一个env来着
ARG[N]
..........
ARG[0]
EIP
EBP //ARG表示涵数的参数,对于MAIN涵数,POSIX定义了两个,历史上有三个的.
因此3语句的作用正好把ESP指向了为ARG[0]保留的地址,也就是跳过为EBP和EIP保留的位置
那么4语句就是为ARG[0]ARG[1]保留位置了
由于MAIN被POSIX规定了两个参数,因此不论有没有都要保留两个位置,又因为没有ARG[2]和MAIN的局部变量,所以把EAX置0,这样一举两得,EAX又可以作为返回值,(通常涵数返回值是INT的,都用EAX表示).
其实大家可能还有不理解,那就是既然涵数的参数都已经压栈了,直接用不就行了?为什么还要拷贝过来呢?
这是C语言的要求,为了局部化,从逻辑上,EBP(含)以上都是属于主调涵数的,所以拷过来当然是必要的.否则C语言如何实现传值而不改变主调涵数的值呢?
整个注释如下:
1:push %ebp
2:mov %esp,%ebp
3:sub $0x8,%esp //为EBP,EIP保留位置
4:and $0xfffffff0,%esp //为ARG[0],ARG[1]保留位置
5:mov $0x0, %eax //一举两用,既作返回值,有表示不需要保留位置
6:sub %eax,%esp //保留0个位置
mov %epb ,%esp //恢复ESP到PUSH %EBP指令时的位置
pop %ebp //恢复EBP的值
ret

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值