首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ret、retn、retf -如何使用它们

ret、retn、retf -如何使用它们
EN

Stack Overflow用户
提问于 2009-09-08 23:40:07
回答 3查看 89.4K关注 0票数 40

我有以下asm代码:

代码语言:javascript
运行
复制
; 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?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-09-09 00:08:07

在助记符ret N中,N是堆栈上参数的大小。在这种情况下,对于4个DWORD,它是4*4= 16 (10h)。

但这仅适用于当被调用者负责堆栈清理时的调用约定。在cdecl约定的情况下,ret应该没有任何数字,因为调用者负责堆栈清理。

票数 34
EN

Stack Overflow用户

发布于 2009-09-08 23:49:06

实际上只有两种不同的返回,retn (近返回)和retf (远返回)。当您只使用ret时,汇编程序或编译器足够聪明,可以选择哪一个是必需的。近返回是到现有代码段内的跳转,远返回是到不同代码段的跳转。在Windows上,你只有一个代码段,所以ret应该只是retn的助记符。单独的retn和retf指令是对以前分段内存模型的一种倒退。目前运行的几乎所有32位x86系统都使用平面内存模型,而不是分段内存模型。

不带参数的Ret将返回地址从堆栈中弹出并跳转到堆栈。一些调用约定(如__stdcall)指定被调用函数清理堆栈。在这种情况下,它们使用字节数调用ret以将这些参数从堆栈中弹出。这16个字节是winmain函数的参数。

票数 69
EN

Stack Overflow用户

发布于 2009-09-08 23:50:26

它实际上有两种类型:retnretf.汇编程序将第三个ret编码为前两个中的一个。

不同之处在于retn (return near)将仅弹出指令指针(IP)。而retf (返回远)将弹出指令指针(IP)和代码段(CS)。

票数 35
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1396909

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档