【汇编】esp寻址与ebp寻址

前言:本教程使用的工具是DTDEBUG,讲解的是32位汇编。

1、什么是esp寻址

        顾名思义,使用esp这个栈顶指针寄存器去寻找变量对应的地址,就叫做esp寻址。

        如下就是一个简单的esp寻址:

        像这样,我们通过esp的偏移来寻找参数的地址,就叫做esp寻址。

        esp寻址的优缺点:

        优点:便捷

        缺点:当遇到复杂的、函数中对堆栈有操作的,esp寻址就会变得有些困难。 

        例如:

        我们之前的测试两数相加,都是把参数从堆栈中取出,放在寄存器里,但实际开发中,寄存器里的值一般情况下都是有用的,说到底就是我们不能直接取出寄存器里的值,我们需要将值备份一份,然后再寻址,使用完成之后再将原来的值取出,如下:

        这也就是esp寻址的缺点所在。

        因此,便有了ebp寻址。

2、什么是ebp寻址

        顾名思义,通过使用ebp寄存器来寻找变量的地址就叫做ebp寻址。

        ebp寻址的优缺点:

        优点:当遇到大量的堆栈操作的时候,寻址并不会变得困难

        缺点:如果只有少量的堆栈操作,ebp还是相对复杂的。 

        这里我们就使用两个参数进行ebp寻址,知道原理即可:

        此时的ebp和esp中间有十六个字节的堆栈是我们自己分配的一块内存,随便用,因为当我们把ebp中的值还给esp的时候,栈顶指针就相当于减了0x10 

        接下来我们将需要用到的寄存器中的值备份到ebp到esp之间的堆栈里:

        为什么不能将eax,push到esp上面的堆栈呢?

        加入我们备份寄存器中的值的时候,不使用ebp到esp之间的地址,我们使用push eax这个指令会怎么样呢?如下:

        我们需要保证函数使用F8执行之后eax里得到的是两个数相加的值,而不是在函数里边得到相加的结果,但是函数执行完了eax又变成原来的值了,这样的函数是没有意义的 

        所以,我们应该把eax被分到ebp到esp之间的堆栈,函数结束后在401219的位置将eax原来的值取出来:

   

       

        将esp的值还给esp,ebp的值还给ebp:

 

        然后返回,这里尽量使用外平栈,不要用retn 8

        因为我们之前将eax值被分到ebp也就是当前的esp+4的位置了,如果我们这个时候将栈顶指针再退两步,那么寻找eax原来的值就变麻烦了,所以先返回函数再取出eax备份,然后再外平栈

        如下:

       

        我们先执行完函数retn看看eax结果对不对:

 

        没有问题,函数的职责尽到了。

        然后取出eax里原来的值:

 

        也没有问题。

        最后外平栈:

 

        至此,ebp寻址完美结束。

总结:esp寻址是用于对堆栈进行少量操作的函数,ebp寻址适用于对对战进行大量操作且需要备份的函数。 

以上便是esp与ebp寻址的全部内容,如果有误望指出,以后大家一起进步。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值