第37章: x64处理器

64位系统中内存地址为64为,因此含有绝对地址的指令大小比原来增加4个字节.

64位可以表示的数为  264   = 16EB .考虑到实际性能,减少内存管理的开销.实际没用到这么多.

 

通用寄存器

通用寄存器大小扩展到64位,数量也增加到18个( 新增 R8~R15 寄存器 ).同时,64位本地模式不使用段寄存器:CS , DS , ES , SS , FS , GS. 它们仅用于向下兼容32位.

第37章: x64处理器

 

Call / JMP 指令

第37章: x64处理器

 

此种 Jmp / Call 会直接跳到绝对地址去. 

第37章: x64处理器

 

64位中,若此种 Jmp 指令采用绝对地址,则会增加指令长度.因此该指令会被解析为相对地址.

 

函数调用约定

32位系统采用的函数调用约定包括 cdecl , stdcall , fastcall . 64位系统中把他们统一为一种变形的 fastcall .

这种调用约定最多可以把函数的四个参数存储到寄存器中传递,第五个参数会存入栈来传递.栈中仍然会为前四个参数(32字节)保留空间.

第37章: x64处理器

并且传递参数过程中所用的栈由调用者清理.

栈/栈帧

调用子函数时,不再使用 Push 命令,而是使用 Mov 指令来传递参数.并且也不再使用 RBP 寄存器,而是直接使用 RSP 寄存器

优点是,调用子函数时不需要改变栈指针( RSP ),函数返回时也不需要清理栈指针.

64位 Main() 函数:

第37章: x64处理器

 

可以看到,代码起始阶段分配了48h字节大小的栈,并且在 ret 指令之前释放.并且几乎没有使用 Push / Pop 指令.

第37章: x64处理器

 

可以看到,CreateFileA() 的参数是乱序传入的,与 32位 C调用的逆序不同.

前四个使用寄存器,从第五个开始使用栈传递.并且,第五个是从 rsp+20h 开始的,即预留了 32d 字节的空间,可以供函数使用.

在 Win7 x64 系统中,CreateFileA() 里面会调用 CreateFileW() :

第37章: x64处理器

 

在 Win 10 64 位系统中,不存在调用 CreateFileW() 的情况:(原因还不太了解)

第37章: x64处理器

 

上一篇:Qt开源作品37-网络中转服务器


下一篇:37_高并发场景下的缓存+数据库双写不一致问题分析与解决方案设计