我正在学习x86程序集。我试图了解“退出程序”如何在x86上工作。我们有一个密码:
push ebp
mov ebp,esp
//Some stuff here
mov esp, ebp
pop ebp
ret当处理器执行指令"ret“时:
EIP将具有从堆栈中弹出的值,换句话说,是0。处理器将进入0地址并尝试执行指令.它不包含程序代码/可执行代码。那么,处理器到底是怎么回事呢?是否有条件检查,例如,if EIP = 0 -> exit program? Or if ESP out of bounds -> exit program?‘如何理解这个RET指令是程序的结束?
发布于 2015-09-06 00:23:35
main()是从普通的C运行时初始化函数调用的。用任何语言(包括asm )编写main与编写任何其他函数没有什么不同。
执行从_start开始。如果编写自己的_start,它没有什么可返回的,因此需要进行_exit(2)或exit_group(2)系统调用。
(否则,当执行从代码的末尾掉下来时,或者如果您尝试ret,它将从堆栈中弹出一个值到程序计数器(EIP)中,并且很可能是从那个可能无效的地址获取代码的分段错误。)
当您使用C编译器编译+链接时,它在CRT (C RunTime)启动代码中链接,该启动代码提供一个初始化libc然后调用main的_start。在您的main atexit 返回后,调用它的CRT代码运行atexit函数,然后将的返回值传递给退出系统调用。
_start不是一个函数,它是进程入口点。例如,在Linux下,在进入_start时,ESP点位于argc,而不是返回地址。(见i386系统V。)
这个问题是从不同的角度提出的,但是我的回答对另一个最近的问题进行了更详细的讨论。
和往常一样,单步调试器是查看发生了什么并测试您的理解的好方法。
发布于 2015-09-05 22:09:02
该进程由操作系统终止。如果您看到一个返回指令,在您的函数之前有一个(“隐藏”)函数,然后返回执行。
在Linux (32位)环境中终止进程的一种方法是调用特定的系统调用:出口。
mov eax, 0 // interrupt code
mov ebx, 0 // argument, in this case: return value
int 0x80这可能是函数之前的功能。上面的代码将命令传递回操作系统,然后操作系统退出您的进程。
https://stackoverflow.com/questions/32415331
复制相似问题