因为
ret是 不是 要退出的Linux,Windows或苹果机的程序的正确方法!!!!
_start
不是函数,因为没有要返回的用户空间调用程序, 所以堆栈上没有返回地址
。用户空间中的执行在进程入口点从此处开始(在静态可执行文件中)。(或者使用动态链接,它在动态链接器完成后跳到此处,但结果相同)。
在Linux / OS X上,堆栈指针指向指向的
argc入口
_start(有关进程启动环境的更多详细信息,请参见i386或x86-64 System
V ABI文档);内核在启动用户空间之前将命令行参数args放入用户空间堆栈内存中。(因此,如果您尝试这样做
ret,则EIP / RIP = argc
=一个小整数,不是有效的地址。如果调试器在地址
0x00000001或其他内容上显示错误,这就是原因。)
对于Windows而言,对于
ExitProcessLinux而言是系统调用- 对于x86,使用
int 80Husing
sys_exit,对于x64而言,使用
syscallusing
60;
exit如果要链接到C库,则从C库进行调用。
32位Linux
mov eax, sys_exit ; sys_exit = 1xor ebx, ebxint 80H
64位Linux
mov rax, 60xor rdi, rdisyscall
视窗
push 0call ExitProcess
或Windows / Linux链接到C库
call exit
exit(与原始退出系统调用或libc不同
_exit),将首先刷新stdio缓冲区。如果
printf从中
_start使用
exit,则即使退出stdout到文件(使stdout成为全缓冲而不是行缓冲),也要确保退出前已打印所有输出。
通常建议,如果使用libc函数,请编写一个
main函数并与gcc链接,以便可以通过常规CRT启动函数调用它
ret。
定义
main为某种东西
_start并不会使其变得特别,
main如果它不像
main由a调用的C
函数
_start那样准备在
main返回后退出,那么使用标签就令人感到困惑。



