我有以下asm代码:
; int __stdcall wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
_wWinMain@16 proc near
var_8= dword ptr -8
var_4= dword ptr -4
hInstance= dword ptr 8
hPrevInstance= dword ptr 0Ch
lpCmdLine= dword ptr 10h
nShowCmd= dword ptr 14h
push ebp
mov ebp, esp
sub esp, 8
mov [ebp+var_4], 5
mov eax, [ebp+var_4]
add eax, 1
mov [ebp+var_8], eax
xor eax, eax
mov esp, ebp
pop ebp
retn 10h
据我所知,你有3种类型的return指令: ret,retn和retf,意思是return,return near和return远。它们允许一个可选的参数nBytes,我猜它是从定义的变量中弹出的字节数。什么时候应该使用retn或retf而不是ret?如何计算可选参数nBytes?
发布于 2009-09-09 00:08:07
在助记符ret N中,N是堆栈上参数的大小。在这种情况下,对于4个DWORD,它是4*4= 16 (10h)。
但这仅适用于当被调用者负责堆栈清理时的调用约定。在cdecl约定的情况下,ret应该没有任何数字,因为调用者负责堆栈清理。
发布于 2009-09-08 23:49:06
实际上只有两种不同的返回,retn (近返回)和retf (远返回)。当您只使用ret时,汇编程序或编译器足够聪明,可以选择哪一个是必需的。近返回是到现有代码段内的跳转,远返回是到不同代码段的跳转。在Windows上,你只有一个代码段,所以ret应该只是retn的助记符。单独的retn和retf指令是对以前分段内存模型的一种倒退。目前运行的几乎所有32位x86系统都使用平面内存模型,而不是分段内存模型。
不带参数的Ret将返回地址从堆栈中弹出并跳转到堆栈。一些调用约定(如__stdcall)指定被调用函数清理堆栈。在这种情况下,它们使用字节数调用ret以将这些参数从堆栈中弹出。这16个字节是winmain函数的参数。
发布于 2009-09-08 23:50:26
它实际上有两种类型:retn
和retf
.汇编程序将第三个ret
编码为前两个中的一个。
不同之处在于retn
(return near)将仅弹出指令指针(IP)。而retf
(返回远)将弹出指令指针(IP)和代码段(CS)。
https://stackoverflow.com/questions/1396909
复制相似问题