• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2023-08-04 15:11 Aet 隐藏边栏 |   抢沙发  12 
文章评分 4 次,平均分 5.0

通用寄存器

RAX

  1. 是一个 64 位寄存器,可以存储 64 位的数据。
  2. RAX 寄存器在 x86 架构中广泛用于存储操作数、函数返回值以及执行算术和逻辑操作。它是通用寄存器,可以用于多种目的。
  3. 调用约定:
    1. 在函数调用中,RAX 寄存器通常用于存储函数的返回值。
    2. 根据不同的调用约定,可能还有其他寄存器用于存储返回值,但 RAX 是最常用的寄存器之一。
  4. 扩展:RAX 寄存器可以在需要时扩展为 128 位或更大的寄存器,如 RAX-EAX-AX-AH-AL
    1. rax-64
    2. eax-rax低32位
    3. ax-eax低16位
    4. ah-ax高8位
    5. al-ax低8位

EBX

  1. 基址寄存器,通常用于存储内存地址。

ECX

  1. 计数器寄存器,用于循环计数和一般计数操作。

EDX

  1. 数据寄存器,常用于存储数据和执行一般算术运算。

ESI

  1. 源变址寄存器,通常用于存储源数据地址。

EDI

  1. 目标变址寄存器,通常用于存储目标数据地址。

ESP

  1. 栈指针寄存器,用于管理栈操作。
  2. 在函数调用时,会使用sub rsp, <size>指令分配局部变量的空间,从而rsp减小,为局部变量腾出位置。
  3. 当函数返回时,会使用leavemov rsp, rbp恢复栈帧,将rsp的值重新调整到原来的位置。

EBP

  1. 基址指针寄存器,通常用于指向栈帧的基址。
  2. 在函数调用时,通常会将调用函数的rbp值保存在栈中,然后将当前的rsp赋值给rbp,从而建立新的栈帧。

段寄存器

CS

  1. 代码段寄存器,用于存储代码段的选择子。

DS

  1. 数据段寄存器,用于存储数据段的选择子。

SS

  1. 堆栈段寄存器,用于存储堆栈段的选择子。

ES- FS- GS

  1. 附加段寄存器,可用于存储其他数据段的选择子。

标志寄存器

EFLAGS

  1. 用于存储和控制各种条件和状态标志,如进位标志、零标志、溢出标志等。

指令寄存器

EIP

  1. 存储当前正在执行的指令的地址。

浮点寄存器

FPU

  1. 用于执行浮点数运算。
  2. 包括多个浮点寄存器 ST0ST1ST2 等。

寄存器代码理解

  1. 将堆栈帧的基址指针压入栈
    1. 栈向下扩展
    2. 不断存入各个函数的堆栈帧的基址指针
  2. 栈寄存器自动指向栈顶,也就是最新的rbp
    1. 也就是说,这个所谓的栈里面保存的是整个函数调用链路上的各个函数的堆栈帧的基址指针

  1. 第一条指令见如上
  2. 第二条指令是将当前栈顶的值赋值给rbp寄存器
    1. 实际上是在这个函数的入口建立了一个新的堆栈帧
  3. 函数执行结束后,通常使用pop rbp将之前保存的rbp值出栈
    1. 同时,rsp恢复到调用函数时的状态

  1. 使用这个指令来恢复栈帧,它会恢复上一个函数的基址指针rbp的值
    1. leave相当于上面的组合
  2. 它会将rbp的值赋给rsp,然后将之前保存的rbp值出栈,恢复外部环境

  1. .zero 用于在目标文件中分配一定数量的字节并初始化为零
  2. aa: 是一个标签(label),.zero 1 表示在标签 aa 处分配一个字节的空间,并将该字节的值初始化为零。

  1. 将值 42 存储到了分配的字节空间中

  1. 最终这个空间的内容就会是 84,因为第二次的存储操作覆盖了第一次的值。

  1. 分配4个字节大小的空间,并挨个赋值

  1. 表示将栈指针 rsp 减去 16 字节,这通常用于为当前函数的局部变量分配内存空间。

参数相关

  1. 常见的 x86-64 调用约定是使用以下寄存器来传递函数参数:
    1. rdi: 第一个参数
    2. rsi: 第二个参数
    3. rdx: 第三个参数
    4. rcx: 第四个参数
    5. r8: 第五个参数
    6. r9: 第六个参数
  2. 如果函数的参数个数超过了这些寄存器的数量,额外的参数会被保存在栈上。

进程地址空间相关介绍

  1. 以下由高地址向低地址:

内核空间

  1. 用途:存储操作系统内核的代码和数据。
  2. 属性:不同于用户空间,通常具有更高的特权级别,可以直接访问硬件。
  3. 增长方向:通常不适用于用户进程的内存管理。

共享库段

  1. 用途:存储共享库(动态链接库)的代码和数据。
  2. 属性:可读写,通常具有执行权限。
  3. 增长方向:正向(向高地址增长)。

栈段

  1. 用途:存储局部变量、函数参数、返回地址等,由系统自动管理。
  2. 属性:可读写,通常不可执行。
  3. 增长方向:反向(向低地址增长)。

堆段

  1. 用途:动态分配的内存块,由程序员手动管理(例如使用 mallocnew 等)。
  2. 属性:可读写。
  3. 增长方向:正向(向高地址增长),但在一些系统中也可以向低地址增长。

BSS段

  1. 用途:存储未初始化的全局和静态变量,它们在程序开始执行之前会被操作系统初始化为零。
  2. 属性:可读写。
  3. 增长方向:正向(向高地址增长)。

数据段

  1. 用途:存储已初始化的全局和静态变量。
  2. 属性:可读写。
  3. 增长方向:正向(向高地址增长)。

代码段

  1. 用途:存储程序的可执行指令。
    1. 代码段中存储的指令是CPU可以直接执行的二进制指令
    2. 这些指令是编写程序的算法和逻辑的具体实现
  2. 属性:只读,通常具有执行权限。
  3. 增长方向:正向(向高地址增长)。

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享