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

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

问题描述

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

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