汇编语言(所有的函数结束都要有ret指令吗?)

符空天 2019-07-02 01:07:36
为什么main函数和add函数结束都有ret指令? call指令和ret指令一般配套使用 add函数结束时的ret指令出栈的是什么东西?(我指的是单独的add函数而不是main函数调用的add函数(虽然这两个是一个函数)) int main() { 011B1410 55 push ebp 011B1411 8B EC mov ebp,esp 011B1413 81 EC E4 00 00 00 sub esp,0E4h 011B1419 53 push ebx 011B141A 56 push esi 011B141B 57 push edi 011B141C 8D BD 1C FF FF FF lea edi,[ebp+FFFFFF1Ch] 011B1422 B9 39 00 00 00 mov ecx,39h 011B1427 B8 CC CC CC CC mov eax,0CCCCCCCCh 011B142C F3 AB rep stos dword ptr es:[edi] int a = 2; 011B142E C7 45 F8 02 00 00 00 mov dword ptr [ebp-8],2 int b = 3; 011B1435 C7 45 EC 03 00 00 00 mov dword ptr [ebp-14h],3 int ret = 0; 011B143C C7 45 E0 00 00 00 00 mov dword ptr [ebp-20h],0 ret = Add(a, b); 011B1443 8B 45 EC mov eax,dword ptr [ebp-14h] 011B1446 50 push eax 011B1447 8B 4D F8 mov ecx,dword ptr [ebp-8] 011B144A 51 push ecx 011B144B E8 91 FC FF FF call 011B10E1 011B1450 83 C4 08 add esp,8 011B1453 89 45 E0 mov dword ptr [ebp-20h],eax return 0; 011B1456 33 C0 xor eax,eax } 011B1458 5F pop edi 011B1459 5E pop esi 011B145A 5B pop ebx 011B145B 81 C4 E4 00 00 00 add esp,0E4h 011B1461 3B EC cmp ebp,esp 011B1463 E8 D3 FC FF FF call 011B113B 011B1468 8B E5 mov esp,ebp 011B146A 5D pop ebp 011B146B C3 ret
...全文
608 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
婉拒达达利亚 2019-07-18
  • 打赏
  • 举报
回复
那就有ret了

不过这样子想,进程就像是OS的一次函数调用啊
zara 2019-07-18
  • 打赏
  • 举报
回复
上面 9#提及的初始化,是指高级语言所做程序的准备部分,不是指电脑的加电初始化。
婉拒达达利亚 2019-07-18
  • 打赏
  • 举报
回复
引用 8 楼 午睡了 的回复:
[quote=引用 6 楼 zara的回复:]截图那里,只是定义函数吧,哪谈得上执行?函数,是 windows的基本模式了,main() 也不是实际程序的开始,只是用户部分的,它也是作为函数的形式被程序初始化部分进行调用的;程序本身,也是由系统以函数形式调用的。

所以初始化程序应该会没有ret指令是吧[/quote]
初始化程序完成初始化和硬件检测后,就开始引导CPU执行,就是把CPU加载到内存中,将CS:IP设置为操作系统的第一条指令所在的内存地址,然后就将CPU控制权交给操作系统了,所以初始化程序没有ret指令。

main函数调用add函数,假设main函数在内存中1000:0处,add函数在内存中1000:200处,main函数里面调用add使用的命令call add,实际的操作相当于push ip然后 jmp near 200(先保存main函数中下一步要执行的命令,然后跳转去执行add,结束后根据ip返回到main继续执行),跳转到add处继续执行,执行完之后因为要返回main函数,需要用ret指令,将栈中放的ip地址取出来继续执行main后面的程序。当然如果你执行add函数后不需要返回原来的函数,是不需要加ret的,根据需要来设计的。
zara 2019-07-09
  • 打赏
  • 举报
回复
初始化先进行些准备,然后调用 main(),由 main()返回后,再做些收尾,也就 ret了。
符空天 2019-07-08
  • 打赏
  • 举报
回复
引用 6 楼 zara的回复:
截图那里,只是定义函数吧,哪谈得上执行?函数,是 windows的基本模式了,main() 也不是实际程序的开始,只是用户部分的,它也是作为函数的形式被程序初始化部分进行调用的;程序本身,也是由系统以函数形式调用的。
所以初始化程序应该会没有ret指令是吧
符空天 2019-07-08
  • 打赏
  • 举报
回复
引用 6 楼 zara的回复:
截图那里,只是定义函数吧,哪谈得上执行?函数,是 windows的基本模式了,main() 也不是实际程序的开始,只是用户部分的,它也是作为函数的形式被程序初始化部分进行调用的;程序本身,也是由系统以函数形式调用的。
谢谢啦,之前没有看,最近又看了些东西,明白了
zara 2019-07-03
  • 打赏
  • 举报
回复
截图那里,只是定义函数吧,哪谈得上执行?函数,是 windows的基本模式了,main() 也不是实际程序的开始,只是用户部分的,它也是作为函数的形式被程序初始化部分进行调用的;程序本身,也是由系统以函数形式调用的。
符空天 2019-07-02
  • 打赏
  • 举报
回复
引用 4 楼 zara的回复:
单独执行add喊上我,怎么执行法,直接jump进去吗,c 不支持这么干吧。
既然定义成了函数的格式,使用上就要按函数调用的规范来,即使有法子直接蹿进去,也要在之前把回来的地址压栈了。
我截图那里不就是执行单独执行add函数,生成了add栈祯,然后他最后有ret指令,我觉得不需要,但是我自己去试了一下确实就是这个
zara 2019-07-02
  • 打赏
  • 举报
回复
单独执行add喊上我,怎么执行法,直接jump进去吗,c 不支持这么干吧。
既然定义成了函数的格式,使用上就要按函数调用的规范来,即使有法子直接蹿进去,也要在之前把回来的地址压栈了。
符空天 2019-07-02
  • 打赏
  • 举报
回复
引用 1 楼 zara的回复:
单独的add函数而不是main函数调用的add函数,这什么说法?函数,就是那个函数,就是被用来调用的;返回,当然就是将控制权转移到调用它的接下来的地方了,出栈的就是返回地址吧,这个返回地址置于 EIP 从而实现执行流程的转移。
你说的我知道 我指的是单独执行add函数,add函数里不是不存在别的函数调用吗?那为什么又ret指令
符空天 2019-07-02
  • 打赏
  • 举报
回复
你说的我知道 我指的是单独执行add函数,add函数里不是不存在别的函数调用吗?那为什么又ret指令
zara 2019-07-02
  • 打赏
  • 举报
回复
单独的add函数而不是main函数调用的add函数,这什么说法?函数,就是那个函数,就是被用来调用的;返回,当然就是将控制权转移到调用它的接下来的地方了,出栈的就是返回地址吧,这个返回地址置于 EIP 从而实现执行流程的转移。

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧