Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 为什么这个x86代码会抛出一个segfault?_Macos_Assembly_Stack_X86 64 - Fatal编程技术网

Macos 为什么这个x86代码会抛出一个segfault?

Macos 为什么这个x86代码会抛出一个segfault?,macos,assembly,stack,x86-64,Macos,Assembly,Stack,X86 64,我试图在x86汇编中添加两个数字2和3。我不再主要使用寄存器,而是从堆栈中推送和弹出值(这是Forth编译器项目的一部分,这就是为什么)。然而,我的代码给了我一个分段错误。我已经在GDB中运行了它,但是回溯并没有给我任何有价值的信息。有人知道我的代码中发生此错误的确切原因吗?(我是这样编译的(在Mac上):gcc-g-mstackreallign-masm=intel-o test test.asm) push-rdi/ret相当于jmp-rdi。像正常人一样返回RAX中的值。e、 g.lea-

我试图在x86汇编中添加两个数字2和3。我不再主要使用寄存器,而是从堆栈中推送和弹出值(这是Forth编译器项目的一部分,这就是为什么)。然而,我的代码给了我一个分段错误。我已经在GDB中运行了它,但是回溯并没有给我任何有价值的信息。有人知道我的代码中发生此错误的确切原因吗?(我是这样编译的(在Mac上):
gcc-g-mstackreallign-masm=intel-o test test.asm


push-rdi
/
ret
相当于
jmp-rdi
。像正常人一样返回RAX中的值。e、 g.
lea-rax,[rdi+rsi]
@Peter-Cordes正如我所说,我没有在rax中返回值的原因是,这段代码来自我正在构建的第四个编译器。在Forth中,结果将被弹出到堆栈中,而不是返回。考虑到这一点,我如何使我的代码工作——而不仅仅是遵循调用约定?显然这是行不通的。您不必在每一步都将第四个堆栈精确地映射到x86-64堆栈,是吗?e、 g.让调用者按下返回值寄存器。或者Forth函数可以在返回之前推送多个东西吗?在这种情况下,在按下返回值之前,您可能会将返回地址弹出到tmp寄存器中。@PeterCordes我会尝试一下,让您知道它是如何运行的。相关但不完全重复:-您可以对堆栈执行奇怪的操作,但是您必须确保调用者和被调用者在所有问题上达成一致,并跳到正确的位置。
push rdi
/
ret
相当于
jmp rdi
。像正常人一样返回RAX中的值。e、 g.
lea-rax,[rdi+rsi]
@Peter-Cordes正如我所说,我没有在rax中返回值的原因是,这段代码来自我正在构建的第四个编译器。在Forth中,结果将被弹出到堆栈中,而不是返回。考虑到这一点,我如何使我的代码工作——而不仅仅是遵循调用约定?显然这是行不通的。您不必在每一步都将第四个堆栈精确地映射到x86-64堆栈,是吗?e、 g.让调用者按下返回值寄存器。或者Forth函数可以在返回之前推送多个东西吗?在这种情况下,您可以在按下返回值之前将返回地址弹出到tmp寄存器中。@PeterCordes我会尝试一下,让您知道它是如何运行的。相关但不完全重复:-您可以对堆栈执行奇怪的操作,但您必须确保调用者和被调用者对所有内容都达成一致,并跳到正确的位置。
    .global _main
    .text
plus:
    add rdi, rsi
    push rdi  # push accumulated rdi value onto stack
    ret
minus:
    sub rdi, rsi
    push rdi
    ret
_main:
    push 2  # push 2 and 3 onto stack
    push 3
    pop rdi  # as preparation for the function call, load rdi and rsi with 2 and 3
    pop rsi
    call plus
    pop rax  # put result into rax
    mov rdi, rax  # then, put the result into rdi
    mov rax, 0x2000001  # exit system call
    syscall