【问题标题】:Assembly x86-64 get function parameters from stack汇编 x86-64 从堆栈中获取函数参数
【发布时间】:2016-10-04 18:55:14
【问题描述】:

最近我一直在从书 Programming from the Ground Up 中学习 x86 汇编,但我有一台 x86-64 计算机,所以事情开始出现问题(在本书的早期阶段)。我到了处理函数的部分,特别是 power 示例。在这个例子中,他将参数压入堆栈,然后在函数的后面将它们复制到寄存器中。他的代码如下所示:

pushl $3                        # second argument
pushl $2                        # first argument
call power                      # call function
...
power:
  pushl %ebp                    # save old base pointer
  movl %esp, %ebp               # make stack pointer the base pointer
  subl $4, %esp                 # get room for our local storage

  movl 8(%ebp), %ebx            # put first argument in %eax
  movl 12(%ebp), %ecx           # put second argument in %ecx

当然,这是 32 位的,而我正在运行 64 位,所以我尝试更新寄存器和指令后缀以得到类似这样的结果(这次应该不需要 cmets):

pushq $3
pushq $2
call power
...
power:
  pushq %rbp
  movq %rsp, %rbp
  subq $4, %rsp

  movq 8(%rbp), %rdi
  movq 12(%rbp), %rsi

鉴于,我可能只是混淆了我应该使用的实际寄存器,但我并不完全确定。我所知道的是,当我在命令 movq 8(%rbp), %rdi 之后在 GNU 调试器中打印 %rdi 的值时,考虑到我得到以下信息,在我看来它似乎具有内存地址而不是它的内容:

(gdb) i r rdi
rdi            0x400081 4194433

另外,有没有像组装爱好者论坛这样的东西?我已经进行了一些基本的搜索,但还没有找到(x86 程序集论坛除外,它只有一个帖子,这是一篇欢迎帖子,http://www.x86-assembly.org/)。

谢谢!

【问题讨论】:

  • 参数不在 x86-64 ABI 的堆栈中。
  • qwords 是 8 字节而不是 4,因此将 movq 8(%rbp), %rdi 更改为 movq 16(rbp)(与下一行相同),您可以使用寄存器作为参数,系统调用需要使用x86-64-abi.
  • Why first parameter is 16($rbp) and not 8($rbp)? 显示了一个具有 10 个整数参数的示例,因此最后 4 个实际上在堆栈上。 (不像这里你发明了自己的调用约定,即使前 2 个 args 也使用 stack-args)

标签: linux function assembly x86-64 stack-memory


【解决方案1】:

标准的 64 位约定不会像那样使用堆栈,它们至少在寄存器中传递前几个参数(类型允许)。当然,对于您自己的代码,您仍然可以使用堆栈。但是,您应该调整偏移量,以便它们使用适当的大小,8 字节而不是 4 字节。

subq $4, %rsp

除非你知道自己在做什么,否则你真的应该使用 8 的倍数。

movq 8(%rbp), %rdi

您希望这是第一个参数,但事实并非如此。它实际上是堆栈上的返回地址,因为现在每个项目都是 8 个字节。所以在0(%rbp)你有推送rbp8(%rbp)是返回地址。因此16(%rbp) 是第一个参数,24(%rbp) 是第二个参数。

请注意,在大多数环境中,您仍然可以编写 32 位代码,因此如果您想继续使用这本书,您可能希望这样做,而不是尝试调整为 64 位。

PS:你会得到一个使用调试器的 cookie :)

【讨论】:

    猜你喜欢
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 2014-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-13
    相关资源
    最近更新 更多