简体   繁体   English

GCC汇编代码显示了64位计算机上的32位寄存器

[英]GCC assembly code shows 32bit registers on 64bit machine

I am trying to learn how to use ptrace library for tracing all system calls and their arguments. 我正在尝试学习如何使用ptrace库跟踪所有系统调用及其参数。 I am stuck in getting the arguments passed to system call. 我被困在传递参数给系统调用。 I went through many online resources and SO questions and figured out that on 64 bit machine the arguments are stored in registers rax(sys call number), rdi, rsi, rdx, r10, r8, r9 in the same order. 我遍历了许多在线资源和SO问题,并发现在64位计算机上,参数以相同的顺序存储在寄存器rax(sys call number), rdi, rsi, rdx, r10, r8, r9中。 Check this website . 检查这个网站

Just to confirm this I wrote a simple C program as follows 为了确认这一点,我编写了一个简单的C程序,如下所示

#include<stdio.h>
#include<fcntl.h>
int main() {
  printf("some print data");
  open("/tmp/sprintf.c", O_RDWR);
}

and generated assembly code for this using gcc -S tc but assembly code generated is as below 并使用gcc -S tc为此生成了汇编代码,但是生成的汇编代码如下

    .file   "t.c"
    .section    .rodata
.LC0:
    .string "some print data"
.LC1:
    .string "/tmp/sprintf.c"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf
    movl    $2, %esi
    movl    $.LC1, %edi
    movl    $0, %eax
    call    open
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4"
    .section    .note.GNU-stack,"",@progbits

As you can see this code is storing parameters on esi and edi instead. 如您所见,此代码将参数存储在esiedi Why is happening? 为什么会这样呢?

Also please guide me on what is the best way to access these passed arguments from these registers/memory location from a C code? 另外,请引导我了解从C代码从这些寄存器/内存位置访问这些传递的参数的最佳方法是什么? How can I figure out if the contents of register is the argument itself or is it a memory location where actual argument is stored? 如何确定寄存器的内容是参数本身还是存储实际参数的存储位置?

Thanks! 谢谢!

this code is storing parameters on esi and edi 此代码将参数存储在esiedi

32-bit instructions are smaller, thus preferred when possible. 32位指令较小,因此在可能的情况下最好使用。 See also Why do most x64 instructions zero the upper part of a 32 bit register . 另请参见为什么大多数x64指令将32位寄存器的高位归零


How can I figure out if the contents of register is the argument itself or is it a memory location where actual argument is stored? 如何确定寄存器的内容是参数本身还是存储实际参数的存储位置?

The AMD64 SystemV calling convention never implicitly replaces a function arg with a hidden pointer. AMD64 SystemV调用约定绝不会用隐藏指针替换函数arg。 Integer / pointer args in the C prototype always go in the arg-passing registers directly. C原型中的整数/指针args总是直接进入arg传递寄存器。

structs / unions passed by value go in one or more registers, or on the stack. 按值传递的结构/联合放在一个或多个寄存器中或堆栈中。

The full details are documented in the ABI . 详细信息记录在ABI中 See more links in the tag wiki. 标签Wiki中查看更多链接。 http://www.x86-64.org/documentation.html is down right now, so I linked the current revision on github. http://www.x86-64.org/documentation.html目前处于关闭状态,因此我在github上链接了当前修订版。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM