以 64 位代码从 [esp] 加载时出现段错误 [英] Segfault when loading from [esp] in 64-bit code
问题描述
我是 x86 程序集的新手,我正在尝试构建一个 hello world 程序.我正在尝试制作一个子程序,将单个字节写入标准输出,但我遇到了问题.
I'm quite new to x86 assembly, and I'm trying to build off a hello world program. I'm trying to make a subroutine, that writes a single byte to stdout, but i've hit a problem.
mov ebx, [esp+1]
行(当我调用子例程时加载传递的字节)会导致段错误.
The line mov ebx, [esp+1]
(to load the byte passed, when I call the subroutine) causes a segfault.
我已尝试将 ebx 寄存器与自身异或,以确保它是空的,以确保它不会与系统调用混淆
I've tried xoring the ebx register with itself, to make sure that it is empty, to make sure, that it doesn't mess with the syscall
_start:
push 32h
call _writeByte
; This just jumps to an exit routine
jmp _exit
_writeByte:
; This line causes the problem. If I remove it the program works fine
mov ebx, [esp+1]
xor ebx, ebx
mov eax, 1
mov edi, 1
mov esi, tmp
mov edx, 1
syscall
ret
为什么程序会出现段错误?
Why is the program segfaulting?
推荐答案
我在 x64 模式下,就像一群人在评论中建议使用 mov ebx, [rsp+8]
工作,因为 esp
只是寄存器的 4 个低字节.堆栈位于虚拟地址空间的低 4 GiB 之外,因此 ESP != RSP 和 [esp]
将是一个未映射的页面.
I'm in x64 mode, and like a bunch of people suggested in the comments using mov ebx, [rsp+8]
worked, because esp
are just the 4 lower bytes of the register. The stack is outside the low 4 GiB of virtual address space, so ESP != RSP and [esp]
will be an unmapped page.
请注意,x86-64 调用约定在寄存器中传递前几个 args,而不是在堆栈中,因此您通常根本不想这样做(除非您的函数有很多 args).
Note that x86-64 calling conventions pass the first few args in register, not on the stack, so you normally don't want to do this at all (unless your function has lots of args).
这篇关于以 64 位代码从 [esp] 加载时出现段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!