有关 intel cpu 上的 x86-64 linux 上的程序集调用约定的问题

问题描述 投票:0回答:1

所以我正在 gdb 中调试一个简单的 c 程序,如下所示,查看程序集

#include <stdio.h>
#include <stdlib.h>

int main() {
  int a = 12;
  printf("%d\n", a);
}

汇编代码如下

0x0000000000001139 <+0>:    push   rbp
   0x000000000000113a <+1>: mov    rbp,rsp
   0x000000000000113d <+4>: sub    rsp,0x10
   0x0000000000001141 <+8>: mov    DWORD PTR [rbp-0x4],0xc
   0x0000000000001148 <+15>:    mov    eax,DWORD PTR [rbp-0x4]
   0x000000000000114b <+18>:    mov    esi,eax
   0x000000000000114d <+20>:    lea    rax,[rip+0xeb0]        # 0x2004
   0x0000000000001154 <+27>:    mov    rdi,rax
   0x0000000000001157 <+30>:    mov    eax,0x0
   0x000000000000115c <+35>:    call   0x1030 <printf@plt>
   0x0000000000001161 <+40>:    mov    eax,0x0
   0x0000000000001166 <+45>:    leave
   0x0000000000001167 <+46>:    ret

变量 a 首先在堆栈中,然后在 eax 中,然后在 esi(rsi) 中,因为 printf 采用一个参数,所以我们最终将数据移动到 rsi 中,这是调用约定中的第二个参数 然而第一个参数“%d “必须通过调用约定以某种方式再次存储在 rdi 中,但是检查 rdi 显示它不存储它。

它是否存储在堆栈中的某个位置,或者 rdi 是否指向它,请向我解释一下,有关调用约定的信息来自此来源

http://6.s081.scripts.mit.edu/sp18/x86-64-architecture-guide.html

尝试将数据转换为字符串或其他东西,但都不起作用

任何帮助将不胜感激

assembly calling-convention
1个回答
0
投票

字符串

"%d\n"
存储在只读数据段中。这一系列指令涉及它:

lea    rax,[rip+0xeb0]    ; retrieve string address
mov    rdi,rax            ; provide string address as first argument

在跳过 LEA 指令后,您可以使用 gdb 命令检查字符串:

printf (char *)$rax
© www.soinside.com 2019 - 2024. All rights reserved.