X86/ARM 寄存器

发布时间 2024-01-13 17:17:49作者: 红旗kernel

1、X86 64寄存器

1.1、x86 通用寄存器16个

寄存器名 寄存器作用
rdi 第一个入参
rsi 第二个入参
rdx 第三个入参
rcx 第四个入参
r8 第五个入参
r9 第六个入参 更多的参数则通过压栈传入
r10--r15   临时数据
rax  

rax 寄存器可以用来存储函数的返回值、临时存储数据以及进行算术和逻辑运算。

一些常见的用途包括:

1、函数返回值: 当函数返回一个整数值时,通常会将该值存储在 rax 寄存器中。例如,C 语言中的 int 类型的函数返回值。

2、临时数据存储: 由于 rax 是通用寄存器,它可以用来存储临时数据,供计算和操作使用。

3、算术和逻辑运算: rax 可以用于执行各种算术和逻辑运算,例如加法、减法、乘法、与、或、异或等。

4、系统调用: 在进行系统调用时,一些返回值或参数可能存储在 rax 寄存器中。

rbx

存储一般性目的的数据

1、函数调用期间,rbx 通常被视为一个可以被调用者保存的寄存器。这意味着如果函数在使用 rbx 寄存器的时候需要保留其值,那么在函数调用结束时,它需要还原 rbx 的值。

2、rbx 寄存器来保存临时数据、计数器值、数组地址等。

rsp

栈向下生长,rsp 寄存器(栈指针)的主要作用是指示栈的当前位置。栈是一种后进先出(Last-In-First-Out,LIFO)的数据结构,用于存储函数调用、局部变量和其他相关信息。

具体而言,rsp 寄存器的作用包括:

1、栈的增长和收缩: rsp 寄存器的值指示栈的顶部,即最新压入的数据的位置。当新的数据被推送到栈上时,rsp 的值减小;当数据从栈上弹出时,rsp 的值增加。

2、函数调用: 在函数调用时,参数和返回地址通常会被推送到栈上。rsp 的值在函数调用前后发生变化,指示栈的新位置。

3、局部变量的分配和释放: 局部变量通常存储在栈上,通过 rsp 寄存器来管理它们的分配和释放。当函数需要分配一些局部变量空间时,rsp 的值减小;当函数退出时,通过增加 rsp 的值来释放这些空间。

4、栈的边界: rsp 的值还用于检查栈的边界。当 rsp 的值超出了栈的范围时,可能触发栈溢出。

rbp

rbp 寄存器(基址指针)的主要作用是用于建立函数的栈帧。栈帧是函数在运行时在栈上创建的局部存储区域,用于存储局部变量、函数参数、返回地址和其他与函数执行相关的信息。

具体而言,rbp 寄存器的作用包括:

1、建立栈帧: 在函数的开头,通常会执行类似以下的指令序列:

assembly
Copy code
push rbp // 保存调用者的栈底
mov rbp, rsp // 设置当前栈帧的基址

 

2、这将调用者的栈底地址保存在新栈帧的基址寄存器 rbp 中,并将当前栈顶地址(栈指针 rsp 的值)赋给 rbp,从而建立了一个新的栈帧。

3、局部变量和参数的访问: 通过 rbp,函数可以轻松访问栈上的局部变量和函数参数。局部变量通常是相对于 rbp 的负偏移,而函数参数通常是相对于 rbp 的正偏移。

4、函数调用和返回: 在函数调用时,调用者将返回地址和其他信息推送到栈上。rbp 的使用使得函数可以准确地找到返回地址。在函数返回时,通过 pop rbp 恢复调用者的栈底,从而撤销当前栈帧。

5、更好的调试信息: 使用 rbp 寄存器建立栈帧可以提供更好的调试信息。调试器可以通过 rbp 寄存器更容易地还原函数调用堆栈,从而更方便地进行源代码级别的调试。

1.2、 x86 64其他常用寄存器

寄存器名 寄存器作用
rip

指令寄存器(RIP)包含下一条将要被执行的指令的逻辑地址。

通常情况下,每取出一条指令后,RIP会自增指向下一条指令。在x86_64中RIP的自增也即偏移一定字节。(可通过disassemble 查看下一个地址,字节大小不一定等长)

但是RIP并不总是自增,也有例外,例如call 指令和ret指令。call指令会将当前RIP的内容压入栈中,将程序的执行权交给目标函数;ret指令则执行出栈操作,将之前压入栈的8个字节的RIP地址弹出,重新放入RIP。

   
   
   
   

 

2 arm 寄存器

2.1armv8 通用寄存器

寄存器名 寄存器作用
x0--x7 传递子程序的参数和返回值,使用时不需要保存。多余参数用堆栈传递,64位cpu 返回结果保存在x0 寄存器中。
x8 保存子程序的返回地址,使用时不需要保存。
x9--x15 临时寄存器,子程序使用时不需要保存。
x16--x17 子程序内部调用寄存器(IPx) ,使用时不需要保存,尽可能不使用
x18 平台寄存器,与平台相关,尽量不使用、ABI 相关
x19--x28 临时寄存器, 子程序使用时必须保存
x29 帧指针寄存器(FP) 用于连接栈帧,使用时必须保存 frame pointer register
x30 链接寄存器(LR) ,用于保存子程序的返回地址。 procedure link register

2.2、其他常用寄存器

寄存器名 寄存器作用
x31 堆栈指针寄存器(SP), 用于指向每一个函数的栈顶  current stack pointer
pc program pointer 存储当前正在执行的指令的地址,指向正在执行的下一条指令

 

3、测试

栈向下生长,栈顶在低地址,栈底在高地址

查看指定地址汇编代码

x/30xi 0x00000000004005e4

查看指定地址的代码数据(堆栈)

x/30x 0x7ffffffac0

3.1 测试程序

#include <stdint.h>

void test_func(int param_1, int param_2, int param_3, int param_4, int param_5, int param_6, int param_7, int param_8, int param_9)
{
    int szArr[10];
    szArr[1] = param_1;
    szArr[2] = param_2;
    szArr[3] = param_3;
}

int main()
{
        int param_1 = 1, param_2 = 2, param_3 = 3;
        int param_4 = 4, param_5 = 5, param_6 = 6;
        int param_7 = 7, param_8 = 8, param_9 = 9;
    test_func(param_1, param_2, param_3, param_4, param_5, param_6, param_7, param_8, param_9);
    return 1;
}