【问题标题】:Assembly function call using stack-based calling conventions使用基于堆栈的调用约定的汇编函数调用
【发布时间】:2021-01-28 08:27:55
【问题描述】:

我很困惑。我正在查看this 页面以了解如何使用堆栈将参数传递给函数。但是,我的代码没有按预期工作。鉴于我将计算结果放入 rax,我希望退出代码为 9,但事实并非如此;相反,我的退出代码是 150。了解 x86 中堆栈的这种调用约定的人是否知道我做错了什么,以及如何实现我想要解决的问题?我正在像这样在 Mac 上使用 GAS 进行组装:gcc -masm=intel stack_frames.asm

    .global _main
    .text
_main:
    push 4  # arg 2
    push 5  # arg 1
    call plus

    mov rdi, rax  # exit code = result in rax, which I'm expecting to be 9
    mov rax, 0x2000001
    syscall

plus:
    push rbp
    mov rbp, rsp

    mov rsi, [rbp + 12]  # param 1
    mov rdi, [rbp + 8]  # param 2
    add rdi, rsi  # sum in rdi
    mov rax, rdi  # move sum to rax

    mov rsp, rbp
    pop rbp
    ret

【问题讨论】:

  • 您希望mov rax, 0x2000001; syscall 做什么?这不是我所知道的任何系统的出口......
  • @ChrisDodd 这就是 OS X 的出口
  • 请注意,64 位调用约定不使用堆栈来传递参数(条件适用)。此外,通常应该有人在 cdecl 中删除参数,这将是调用者。当然,既然你立即退出,这不是问题。

标签: macos function assembly x86-64 callstack


【解决方案1】:

您使用的是 64 位的 x86-64,而不是 32 位 x86。您知道这一点是因为您能够使用像 rax 这样的 64 位寄存器。因此,pushcall 推送 8 个字节,而不是 4 个,因此您的参数将位于 [rbp + 24][rbp + 16],而不是 [rbp + 12][rbp + 8]

【讨论】:

  • 完美。谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-03-14
  • 2017-06-03
  • 2014-07-12
  • 2019-11-22
  • 2018-04-28
  • 2011-03-26
  • 1970-01-01
  • 2015-04-08
相关资源
最近更新 更多