X86-64 CPU架构以及64 位GCC对程序编译处理的一些变化

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/youkawa/article/details/45458921

X86-64 CPU架构以及64 位GCC对程序编译处理的一些变化

作者:JochenZou
转载请注明出处:http://blog.csdn.net/youkawa/article/details/45458921

  1. 通用寄存器全部扩展到了64位,寄存器名称前面由R开头,如RAX, RBX, RCX, RDX, RSI和RDI
  2. 指令指针(Instruction pointer)、基址指针(base pointer)以及堆栈指针(stack
    pointer)也全部扩展到了64位,这些专用寄存器分别称为RIP,RBP,RSP
  3. 添加了8个通用寄存器R8~R15
  4. 指针长度为64位即8-bytes长度;
  5. 涉及到栈操作的Push/pop指令入栈出栈操作数的长度为64位即8-bytes长度;
  6. 函数参数主要依靠6个寄存器来传递,当寄存器不够用时才把参数压入栈中存储。按存储参数的顺序(从左到右)依次为RDI, RSI, RDX, RCX, R8, R9
  7. 最大canonical address大小为0x00007FFFFFFFFFFF.
  8. GCC对函数局部变量分配的空间大小为16字节的倍数,例如分配char a[15],则回从[RBP-0X10]地址开始存放局部变量,若定义char a[17],则从[RBP-0X20]地址开始存放局部变量;
  9. GCC对函数局部变量分配空间有以下几种方式:
    (1)当函数内部有调用其他外部函数(有CALL指令)的时候,使用SUB RSP , 0xXX指令分配栈空间, 然后使用MOV [RBP-X], 0xXX的形式入栈,如果没有对局部变量初始化,而且函数后面也没有使用这一变量,则GCC不会为其开辟空间。
    (2)当函数内部没有调用其他外部函数时,在进行prologue操作(即push rbp; mov rbp, rsp)之后,不会有SUB RSP , 0xXX指令开辟栈空间的操作,而是直接使用MOV QWORD PTR [RBP-0xXX], 0xXX的方式直接使用栈空间;
    (3)当函数内部静态调用lib库函数的时候,因为此时被调用函数内联到了主调函数里面,所以不会有CALL指令,仍然按(2)的方式操作。

猜你喜欢

转载自blog.csdn.net/youkawa/article/details/45458921