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

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

作者:Jochen1986

转载请注明出处: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)的方式操作。

时间: 2024-10-01 03:30:34

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

64位gcc编译32位汇编

由于使用as和ld来编译链接汇编程序,在使用C库的时候比较麻烦,需要输入比较多的指令,所以使用gcc进行编译链接.由于书中内容是32位汇编程序,但是机器使用的是64位操作系统,自带的gcc也是64位的,导致编译生成的程序,一运行就会Segment Fault.经过查询之后,发现是调用printf函数的时候,总是报错,查询之后发现是32位汇编和64位汇编在调用C库的时候,32位使用pushl指令来压栈传递参数,而64位汇编是使用通用寄存器来传递参数的. 32汇编的代码是: 1 .code32 2

64位系统上设置编译平台为x86的项目编译在特定的情况下比如当一个窗体上放有包含了图像的ImageList之后,ResGen就会产生这种问题

随笔 - 1  文章 - 0  评论 - 3 未能加载文件或程序集“****”或它的某一个依赖项.试图加载格式不正确的程序.解决方案总结 当这个ImageList中没有图像时编译也是正常的,但是一旦编译就会引发这样的异常. 这个错误产生的原因在于,VS2010内部使用的编译器中,无论是32位还是64位的编译组件,都是纯IL的,也就是在64位系统中是以64位模式运行,这与当前项目使用的平台设置无关.当编译的组件引用了一个标记为x86的库(仅32位模式)时,编译组件便会发生错误,无法加载,从而导致编

Linux江湖08:使用GCC和GNU Binutils编写能在x86实模式运行的16位代码

不可否认,这次的标题有点长.之所以把标题写得这么详细,主要是为了搜索引擎能够准确地把确实需要了解GCC生成16位实模式代码方法的朋友带到我的博客.先说一下背景,编写能在x86实模式下运行的16位代码,这个话题确实有点复古,所以能找到的资料也相应较少.要运行x86实模式的程序,目前我知道的只有两种方式,一种是使用DOS系统,另一种是把它写成引导扇区的代码,在系统启动时直接运行.很显然,许多讲自己实现操作系统的书籍都会讲到x86实模式,也只有自己实现操作系统引导的朋友需要用到x86实模式,所以我这篇

Linux 桌面玩家指南:08. 使用 GCC 和 GNU Binutils 编写能在 x86 实模式运行的 16 位代码

特别说明:要在我的随笔后写评论的小伙伴们请注意了,我的博客开启了 MathJax 数学公式支持,MathJax 使用$标记数学公式的开始和结束.如果某条评论中出现了两个$,MathJax 会将两个$之间的内容按照数学公式进行排版,从而导致评论区格式混乱.如果大家的评论中用到了$,但是又不是为了使用数学公式,就请使用\$转义一下,谢谢. 想从头阅读该系列吗?下面是传送门: Linux 桌面玩家指南:01. 玩转 Linux 系统的方法论 [约 1.1 万字,22 张图片] Linux 桌面玩家指南

[MinGW]_[初级]_[64位的windres如何编译32位的链接文件]

场景: 1.   MinGW(TDM)出了64位的gcc,4.8.1,64位对编译64位的程序非常友好,但是对编译32位程序就需要做额外的工作了. 2.  比如用windres编译manifest,64位环境下默认是不行的,带configure或makefile的即使加了-m32都不会自动对windres设置为编译32位的. 这里就需要在configure或make增加一些参数了. ./configure RCFLAGS="--output-format=coff --target=pe-i38

64位CentOS 6.5编译配置ACE 6.1.0(6.2.0)

系统:CentOS 6.5 64位 ACE版本:6.1.0 假定压缩文件目录为:/usr/local/ 步骤1: 解压下载好的ACE-6.1.0.tar.gz # tar zxvf ACE-6.1.0.tar.gz 出现一个名为:ACE_wrappers的文件夹 步骤2:定义环境变量: 修改/etc/profile 或者 /etc/bashrc # vi /etc/profile 加入以下两行: ACE_ROOT=/usr/local/ACE_wrappers;export ACE_ROOT L

使用VS2008,VS2010编译64位的应用程序

要编译生成64位的应用程序,就必须把vs2008,或vs2010的配置管理器设置为x64. 如果你的配置管理器那里没有x64这个选项,那么是你在安装vs时可能没有安装这个组件.你不用卸载vs,只需打开你原来的安装包,安装上X64的编译.链接组件等即可.(就是在功能选择里,在VC++节点下,要选择X64编译器和工具.) 使用 x64 编译器和工具可以在 Win32 或 Win64 平台上开发 64 位应用程序. 这包括编译器:链接器:包括头文件和源代码的 C 运行时库.MFC.ATL 和标准模板库

[DEV] 在linux 64 系统下面进行32位程序开发

因为调试的需要,我需要在64位的机器下编译32位的目标文件. 运行make 命令的时候,出现以下错误 fatal error: gnu/stubs-32.h: No such file or directory 意识到,我这是一台64位的系统,还未安装相应的开发包.我们缺少32位应用程序所需要的库及相及的头文件 yum install glibc-devel.i686 yum install libstdc++-devel.i686 安装完上面两个包,重新运行make. OK,Done.

判断是64位操作系统还是32位系统

1.IsWow64Process 确定指定进程是否运行在64位操作系统的32环境(Wow64)下. 语法 BOOL WINAPI IsWow64Process( __in HANDLE hProcess, __out PBOOL Wow64Process ); 参数 hProcess 进程句柄.该句柄必须具有PROCESS_QUERY_INFORMATION 或者 PROCESS_QUERY_LIMITED_INFORMATION 访问权限 Wow64Process 指向一个bool值, 如果该