汇编加法

1.  _add_a_and_b:
    2.   push   %ebx
    3.   mov    %eax, [%esp+8] 
    4.   mov    %ebx, [%esp+12]
    5.   add    %eax, %ebx 
    6.   pop    %ebx 
    7.   ret  

8.  _main:
    9.   push   3
    10.  push   2
    11.  call   _add_a_and_b 
    12.  add    %esp, 8
    13.  ret

首先程序从_main开始,也就是第九行。
push 3 意思是将3压入栈(栈的顶部是地址小的区域,压入栈的数据越多,esp越小)。注意在push之前是有前置操作的,由于3是int类型的所以是4个字节。所以esp得-4个字节,因为这边是从高位到低位所以是减法。
假设这段程序系统分配的内存地址是0x1000~0x0000;
那么现在寄存器里存放的内存地址由原先的0x1000变为0x0ffd

栈里对应分配4个字节的内存空间,下面是内存地址和值对应:
0x1000 0
0x0FFF 0
0x0FFE 0
0x0FFD 3

然后执行push 2 esp再次减4字节这个时候(esp存的内存地址为0x0FE9):
0x0FFC 0
0x0FFB 0
0x0FFA 0
0x0FE9 2

接下来执行第11行 call _add_a_and_b 的时候,call关键字会创建一个该函数用的帧。
第2行代码push %ebx 事先把原来ebx寄存器里面的值压入栈(因为需要借用寄存器ebx来进行计算,等会会将压入栈的内容还回来,相当于temp变量,push指令会再将 ESP 寄存器里面的地址减去4个字节(累计减去12)这个时候esp存的内存地址为0x0FE5)
执行第3行 mov %eax, [%esp+8] 将 esp内存地址(0x0FE5)加上8,这个时候esp内存地址是(0x0FFC),然后就是将0x0FFC~0x0FE9的值赋值给eax(为什么eax不用push呢因为eax用的比较频繁原来的值不保留也没关系)
那么eax里的四个字节,假设他们为字节A,字节B,字节C,字节D:
字节A=0
字节B=0
字节C=0
字节D=2

接下来执行第4行mov %ebx, [%esp+12] ,跟上面一样,把0x1000~0x0FFD中的内容给了ebx

第五行add %eax, %ebx
add指令的意思是将第二个参数也就是ebx的值和第一个参数eax的值相加复制到eax
执行完了以后
eax是{0,0,0,5}
ebx是{0,0,0,3}

执行第6行pop %ebx 将原先ebx中的值替换ebx现在的{0,0,0,3}变成{?,?,?,?}(因为在这段过程中我不知道ebx的原先值),既然push指令会减4个字节,那么pop也会加4个字节吧

第7行ret 是函数调用结束,回收帧

第12行. add %esp, 8 手动将esp寄存器的地址加回来,而使用的那些内存不会再用会被回收。

在这边回收的意思是值,我往内存里写入值不用在意内存里面是不是是有值的。我只要告诉寄存器内存地址就行了。如果上面寄存器的内存地址不加8加回来,那么0x1000~0x0FE9的内存就永远空置在那里了,从而也可以理解为什么delphi debug的时候有些内存有奇怪的值了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值