Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux RET in\U启动时的Nasm分段故障_Linux_Assembly_X86_Nasm - Fatal编程技术网

Linux RET in\U启动时的Nasm分段故障

Linux RET in\U启动时的Nasm分段故障,linux,assembly,x86,nasm,Linux,Assembly,X86,Nasm,我使用以下命令进行编译: section .text global _start _start: nop main: mov eax, 1 mov ebx, 2 xor eax, eax ret 当我运行代码时,Linux抛出一个分段错误 (我使用的是LinuxMintNadia64位)。为什么会产生此错误?因为ret不是退出Linux、Windows或Mac中程序的正确方法 \u start不是一个函数,堆栈上没有返回地址,因为没有

我使用以下命令进行编译:

section .text
     global _start
_start:
     nop
main:
     mov eax, 1
     mov ebx, 2
     xor eax, eax
     ret
当我运行代码时,Linux抛出一个分段错误


(我使用的是LinuxMintNadia64位)。为什么会产生此错误?

因为
ret
不是退出Linux、Windows或Mac中程序的正确方法

\u start
不是一个函数,堆栈上没有返回地址
,因为没有要返回的用户空间调用方。用户空间中的执行从这里开始(在静态可执行文件中),在流程入口点。(或者使用动态链接,它在动态链接器完成后跳到这里,但结果相同)

在Linux/OS X上,堆栈指针指向
\u start
条目上的
argc
(有关进程启动环境的更多详细信息,请参阅i386或x86-64 System V ABI文档);内核在启动用户空间之前将命令行参数放入用户空间堆栈内存。(因此,如果您确实尝试
ret
,EIP/RIP=argc=一个小整数,而不是一个有效的地址。如果调试器在地址
0x00000001
或其他位置显示错误,这就是原因。)


对于Windows,它是ExitProcess,Linux是系统调用-
int 80H
对于x86使用
sys\u exit
,对于64位使用
60
或从C库调用
exit
(如果您正在链接到它)

32位Linux

nasm -f elf main.asm
ld -melf_i386 -o main main.o
mov     eax, sys_exit ; sys_exit = 1
xor     ebx, ebx
int     80H
64位Linux

nasm -f elf main.asm
ld -melf_i386 -o main main.o
mov     eax, sys_exit ; sys_exit = 1
xor     ebx, ebx
int     80H
窗口

mov     rax, 60
xor     rdi, rdi
syscall

或针对C库的Windows/Linux链接

push    0
call    ExitProcess
exit
(与原始exit系统调用或libc
\u exit
不同)将首先刷新stdio缓冲区。如果从
\u start
使用
printf
,请使用
exit
确保在退出之前打印所有输出,即使stdout被重定向到文件(使stdout完全缓冲,而不是行缓冲)

一般建议,如果使用libc函数,您可以编写一个
main
函数并与gcc链接,这样就可以通过正常的CRT启动函数调用它,您可以
ret
调用它


main
定义为
\u start
所包含的内容并不意味着它特别,如果一个
main
标签不像一个
\u start
调用的C
main
函数,它准备在
main
返回后退出,那么使用
main
标签会让人感到困惑。

应该是返回代码,而不是这样的(Linux):
mov eax,1 mov ebx,0 int 80h
在我看来,由于最后一行中的
ret
,您得到了分段错误。@maxiperez根本不是一个愚蠢的问题:)。它表明程序不仅仅是一个“主要”功能,它们还以不同的方式与操作系统交互。