码迷,mamicode.com
首页 > 其他好文 > 详细

GCC X64

时间:2015-03-30 18:57:54      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:通用寄存器 栈 frame gcc

    在 Linux/C 环境中横行几年后,越发体会到汇编对于 GDB 的重要。在开始前,先来看一段 sample:

#include<stdlib.h>
#include<stdio.h>
/*这个函数没有任何地方调用过 */
void why_here(void) {
    printf("why u here ?!\n");
    exit(0);
}

int main(int argc,char * argv[]) {
    long long buff[1];
    buff[3]=(long long)why_here;
    return 0;
}

    不带 -O 编译后发现,why_here 居然被调用了!

    很神奇是吧?想要知道为什么,就得开始了解 x64 寄存器、汇编、Frame 和 stack 等,Let‘s start!

一. 通用寄存器

    x86-64 与 x86 并不是同一个概念,且实际上变化挺大的,包括寄存器个数、传参方式等。鉴于 x86-64 已经是主流,最起码在阿狸的服务器上是主流(呃,alipay 不思进取,不包括在内),因此,x86 的相关实现就不列举了。毕竟,对过去了解得越多,除了证明你已经老了,并不能体现你现在有多牛B。

    1. 寄存器数目

    新增加寄存器 %r8 到 %r15,加上 x86 的原有 8 个,一共 16 个寄存器,分别是:%rax, %rbx, %rcx, %rdx, %rsi, %rdi, %rbp, %rsp, %r8, %r9, %r10, %r11, %r12, %r13, %r14, %r15。

    2. 寄存器长度

    x86-64 中的寄存器都是 64 位的,相对于 x86 来说,标识符发生了变化,比如:从原来的 %ebp 变成了 %rbp。为了向后兼容性,%ebp 依然可以使用,不过指向了 %rbp 的低 32 位。

    3. 寄存器使用方法

    所谓的通用,意味着在使用上没有限制,接下来提到的规则,仅仅是 GCC 遵循的规则。这些内容必须记住!

  • %rax 作为函数返回值使用

  • %rsp 栈指针寄存器,指向栈顶 (stack pointer)

  • %rbp 栈指针寄存器,指向栈底 (bottom pointer)

  • %rdi,%rsi,%rdx,%rcx,%r8,%r9 用作函数参数,依次对应第1参数,第2参数。。。

  • %rbx,%rbp,%r12,%r13,%14,%15 用作数据存储,遵循被调用者使用规则,简单说就是随便用,调用子函数之前要备份它,以防它被修改

  • %r10,%r11 用作数据存储,遵循调用者使用规则,简单说就是使用之前要先保存原值

  • %rip  下一条待执行的指令 (instruction pointer)


二. Frame

    对应 GDB 中的 frame 指令,可以在调用栈中切换到不同的函数。因此,可以简单的将函数对应为 Frame。%rbp 和 %rsp 指向 Frame 的底和顶。

本文出自 “wilber” 博客,谢绝转载!

GCC X64

标签:通用寄存器 栈 frame gcc

原文地址:http://wilber1202.blog.51cto.com/8738232/1626481

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!