【发布时间】:2011-05-16 14:24:48
【问题描述】:
ret instruction 是否会导致“esp”寄存器增加 4?
【问题讨论】:
标签: assembly x86 return instructions stack-pointer
ret instruction 是否会导致“esp”寄存器增加 4?
【问题讨论】:
标签: assembly x86 return instructions stack-pointer
是的,当处理器在 32 位保护模式下运行时。在实模式或 16 位保护模式下,RET 执行 POP IP,这将导致 ADD ESP,2(而不是 4)。
【讨论】:
是的,因为在堆栈上有(嗯,应该有,参见缓冲区溢出)恢复程序执行的地址。所以 ret 意味着
pop ret_addr ; pop deletes ret_addr from stack by adding 4 to esp
mov eip, ret_addr
这是
pop eip
正如鲁斯利克所说的
【讨论】:
是的,它执行
pop eip
你可以使用
mov eax, [esp]
jmp eax
避免它。
编辑:这正是ret 所做的。例如,jmp rel_offet 就是一个隐藏的add eip, offset,或者jmp absolute_offset 就是mov eip, absolute_offset。当然,处理器处理它们的方式有所不同,但从程序员的角度来看,这就是发生的一切。
另外,ret 的特殊形式:ret imm8 也将此 imm8 值添加到 esp:例如,__stdcall 函数使用它从堆栈中丢弃其参数。更不用说retf版本,在16位模式下使用,它也会从堆栈中弹出cs。
EDIT2:
pop register
意思是:
mov register, [esp]
add esp, 4
【讨论】:
jmp target_of_jump 是直接修改eip的方式(因为mov eip, target_of_jump不行)。有关 Intel 64 和 IA32 组件的详细信息,我推荐“Intel® 64 和 IA-32 架构软件开发人员手册”:intel.com/products/processor/manuals BTW:除非我在 ARM 处理器上弄错了,否则您可以直接读/写程序计数器(它是寄存器 15那里)。