我有以下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
Run Code Online (Sandbox Code Playgroud)
从我读到的,你有3种类型的返回指令:ret,retn和retf,意思是返回,返回附近和返回远.它们允许一个可选的参数nBytes,我想这是从定义的变量中弹出的字节数.什么时候应该使用retn或retf而不是ret?如何计算可选参数nBytes?
Mic*_*ael 60
实际上只有两个不同的回报,retn(靠近返回)和retf(远回归).当你只使用ret时,汇编器或编译器足够聪明,可以选择哪一个是必需的.near return是在现有代码段内的跳转,far return是跳转到不同的代码段.在Windows上,您只有一个代码段,因此ret应该只是retn的助记符.当分段记忆模型很常见时,单独的retn和retf指令是旧时代的回归.几乎所有今天运行的32位x86系统都使用扁平的,而不是分段的内存模型.
没有参数的Ret弹出堆栈的返回地址并跳转到它.一些调用约定(如__stdcall)指定被调用函数清除堆栈.在这种情况下,他们调用ret的字节数来从堆栈中弹出这些参数.16个字节是winmain函数的参数.
Max*_*Max 28
在助记符N中,N是堆栈上参数的大小.在这种情况下,对于4个DWORD,它是4*4 = 16(10h).
但这仅适用于被调用者负责堆栈清理时调用约定.在cdecl约定的情况下,ret应该没有任何数字,因为调用者负责栈清理.
Azi*_*ziz 24
它实际上有两种类型:retn和retf.第三个ret由汇编程序编码为前两个中的一个.
不同之处在于retn(返回附近)将仅弹出指令指针(IP).而retf(返回far)将弹出指令指针(IP)和代码段(CS).
| 归档时间: |
|
| 查看次数: |
72513 次 |
| 最近记录: |