以 64 位代码从 [esp] 加载时出现段错误 [英] Segfault when loading from [esp] in 64-bit code

查看:22
本文介绍了以 64 位代码从 [esp] 加载时出现段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆