在 64 位代码中从 [esp] 加载时出现段错误
Segfault when loading from [esp] in 64-bit code
我对 x86 汇编很陌生,我正在尝试构建一个 hello world 程序。我正在尝试制作一个子例程,将单个字节写入标准输出,但我遇到了问题。
行mov ebx, [esp+1]
(加载传递的字节,当我调用子程序时)导致段错误。
我试过对 ebx 寄存器本身进行异或运算,以确保它是空的,以确保它不会与系统调用混淆
_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
为什么程序会出现段错误?
我在 x64 模式下,就像一群人在评论中建议使用 mov ebx, [rsp+8]
一样有效,因为 esp
只是寄存器的 4 个低字节。堆栈位于虚拟地址 space 的低 4 GiB 之外,因此 ESP != RSP 和 [esp]
将是未映射的页面。
请注意,x86-64 调用约定在寄存器中传递前几个参数,而不是在堆栈中传递,因此您通常根本不想这样做(除非您的函数有很多参数)。
我对 x86 汇编很陌生,我正在尝试构建一个 hello world 程序。我正在尝试制作一个子例程,将单个字节写入标准输出,但我遇到了问题。
行mov ebx, [esp+1]
(加载传递的字节,当我调用子程序时)导致段错误。
我试过对 ebx 寄存器本身进行异或运算,以确保它是空的,以确保它不会与系统调用混淆
_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
为什么程序会出现段错误?
我在 x64 模式下,就像一群人在评论中建议使用 mov ebx, [rsp+8]
一样有效,因为 esp
只是寄存器的 4 个低字节。堆栈位于虚拟地址 space 的低 4 GiB 之外,因此 ESP != RSP 和 [esp]
将是未映射的页面。
请注意,x86-64 调用约定在寄存器中传递前几个参数,而不是在堆栈中传递,因此您通常根本不想这样做(除非您的函数有很多参数)。