从[esp]以64位代码加载时出现段错误 [英] Segfault when loading from [esp] in 64-bit code
问题描述
我对x86汇编很陌生,并且我正在尝试构建一个hello world程序.我正在尝试创建一个子例程,该子例程将单个字节写入stdout,但是我遇到了问题.
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寄存器与其自身进行异或,以确保它为空,以确保它不会与syscall混淆
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调用约定在寄存器中而不是在堆栈中传递前几个arg,因此您通常根本不想这样做(除非您的函数有很多arg).
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).
这篇关于从[esp]以64位代码加载时出现段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!