• 第37章: x64处理器


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

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

    通用寄存器

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

    Call / JMP 指令

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

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

    函数调用约定

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

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

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

    栈/栈帧

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

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

    64位 Main() 函数:

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

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

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

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

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

  • 相关阅读:
    群晖下 gitea+drone+harbor实现CI/CD 发布到云服务器
    随便写写
    知行合一
    GO/testing包
    进程切换时是如何保存上下文的
    语言
    printf缓冲区踩坑
    Spring 中 @EnableXXX 注解的套路
    分享一个工业现场常用的运动控制案例
    数据库之App.config配置文件错误
  • 原文地址:https://www.cnblogs.com/Rev-omi/p/13503919.html
Copyright © 2020-2023  润新知