x86汇编指令寄存器

在X86指令集中寄存器分为四类:通用寄存器、指令指针寄存器、段寄存器、标志寄存器。

数据寄存器EAX(Accumulator) 累加器,RAX可作为64位寄存器(RAX)、32位寄存器(EAX)、16位寄存器(AX)或两个8位寄存器(AH或AL)引用。该寄存器用于乘法、除法及一些调整指令。 EBX(Base) 基址,RBX可作为RBX、EBX、BX、BH或BL寻址。该寄存器有时用于保存访问存储单元的偏移量。在80386及更高型号的CPU中,EBX也能寻址存储器数据;在64位的P4和Core2中,RBX也能寻址存储器数据。 ECX(Count) 计数,RCX可作为RCX、ECX、CX、CH或CL寻址,它是一个通用寄存器,也可保存许多指令的计数值。在80386及更高型号的CPU中,ECX可保存访问存储器数据的偏移量;在64位的P4,RCX也可以寻址存储器数据。 用于计数的指令是重复的串指令(REP/REPE/REPNE)以及移位、循环和LOOP/LOOPD指令。

移位和循环指令用CL计数

重复的串指令用CX计数

LOOP/LOOPD指令用CX或ECX计数

LOOP指令使用64位RCX寄存器进行循环计数(在64位模式操作下)
EDX(Data) 数据,RDX可作为RDX、EDX、DX、DH或DL寻址,它是通用寄存器,用于保存乘法形成的部分结果,或者除法之前的部分被除数。在80386及更高型号的CPU中,可寻址存储器数据。   
指针变址寄存器EBP(Base Pointer) 扩展基址,RBP可作为RBP、EBP或BP寻址,为了用于传送存储器数据,RBP指向存储单元。ESP(Stack Pointer)堆栈ESI(Source Index) 源,RSI可作为RSI、ESI或SI使用。通常为串指令寻址源数据串。同RDI一样,RSI也作为通用寄存器使用。如果它作为16位寄存器,就由SI寻址;如果作为32位寄存器,就由ESI寻址;如果作为64位寄存器,就由RSI寻址EDI(Destination Index) 目的, RDI可作为RDI、EDI或DI寻址,常用于寻址串指令的目的数据串  
指令指针寄存器EIP(Instruction Pointer) 指令指针寄存器,寻址代码段存储区内的下一条指令,也可由转移指令或调用指令修改

a. 实模式下:寄存器是IP(16位)

b. 保护模式下:寄存器是EIP(32位)

c. 64位模式下:RIP包含40位地址总线,可用于寻址1TB平展模式地址空间

2. RSP(堆栈指针):寻址一个称为堆栈的存储区。

a. 作为16位寄存器被引用时,为SP

b. 作为32位寄存器被引用时,为ESP
     
段寄存器CS(Code Segment) 代码段,保存微处理器使用的代码(程序和过程),它定义了存放代码的存储器段的起始地址

a. 实模式下:定义了一个64KB存储器段的起始地址

b. 保护模式:选择一个描述代码存储器起始地址和长度的描述符

c. 在8086 - 80286下:限制为64KB

d. 在80386及更高型号的微处理器工作在保护模式下:代码段限制为4GB

e. 在64位模式下,代码段寄存器仍然应用于平展模式
DS(Data Segment) 数据段,包含程序使用的大部分数据,可以通过偏移地址或其他含有偏移地址的寄存器的内容访问数据段里的数据

a. 在8086 - 80286下:限制为64KB

b. 在80386及更高型号的微处理器工作在保护模式下:代码段限制为4GB
SS(Stack Segment) 堆栈段,为堆栈定义一个存储区域。由堆栈段和堆栈指针寄存器确定堆栈段内当前的入口地址。ES  附加数据段,为某些串指令存放目的数据FS 附加数据段,在80386 - Core2微处理器中增加的段寄存器GS 附加数据段,在80386 - Core2微处理器中增加的段寄存器
标志寄存器FLAGS或PSW  标志寄存器     
条件标志寄存器OF(OverFlow Flag) 溢出SF(Sign Flag) 符号ZF(Zero Flag) 零AF(Auxilliary carry Flag) 辅助进位PF(Parity Flag) 奇偶CF(Carry Flag) 进位
控制标志寄存器DF(Direction Flag) 方向IF(Interupt Flag) 中断TF(Trap Flag) 陷阱   

其中数据寄存器和指针变址寄存器寄存器在64/32/16/8中名字有所差异,如下:

64位32位16位8位
raxeaxaxal/ah
rbxebxbxbl/bh
rcxecxcxcl/ch
rdxedxdxdl/dh
rsiesisi-
rdiedidi-
rbpebpbp-
rspespsp-
r8~r15r8d~r15dr8w~r15wr8b~r15b

不同体系结构的CPU在其内部存在的寄存器的数量、类型以及名称可能会不同,比如ADM64 CPU这一种体系结构,这种CPU在其内部存在二十多个可直接被汇编语言中使用的调度器,还有几种仅在操作系统代码中才会出现,应用层的话,通常只会用到如下三个分类共19个调度器:

1. 通用寄存器。共有rax、rbx、rcx、rdx、rsi、rdi、rbp、rsp、r8、r9、r10、r11、r12、r13、r14、r15这16个寄存器,CPU对它们的用途没有做特殊规定,可以自定义其用途(其中rsp、rbp这两个寄存器有特殊用途)。

其中,rsp栈顶寄存器以及rbp栈基寄存器都和函数调用栈相关,其中rsp寄存器一般用来存放函数调用栈的栈顶在内存中的地址,rbp寄存器通常用来存放函数的栈帧在内存中的起始地址。

2. 程序计数寄存器(rip寄存器,也叫PC寄存器、IP寄存器)。用来存放下一条即将用来执行的指令的地址,它决定程序执行的流程。

rip寄存器中存储的值不是CPU正在执行的指令在内存中的地址,而是紧随其后那一条将要被执行的指令在内存中的地址。修改rip寄存器中的值这个操作是CPU自动控制的,不需要通过指令去修改,CPU对外也提供了几条间接修改rip寄存器的指令。

3· 段寄存器(fs、gs寄存器)。用来实现线程本地存储(TLS),比如ADM64 Linux下Go语言和pthread线程库都用fs存储器来实现线程的TLS(本地存储)。

### x86汇编中的寄存器相关指令 在x86架构中,寄存器扮演着至关重要的角色。它们被用来存储临时数据,并且其位宽必须与操作数的位宽保持一致[^2]。以下是常见的与寄存器相关的指令及其功能: #### 数据传输类指令 这些指令主要用于在寄存器之间、内存和寄存器之间移动数据。 - **MOV** `mov` 是最常用的指令之一,用于将数据从源地址复制到目标地址。它支持多种寻址模式,可以用于寄存器之间的数据传递以及寄存器与内存之间的交互[^1]。 ```asm mov eax, ebx ; 将ebx的内容复制到eax ``` - **XCHG** 这条指令交换两个操作数的数据内容,其中一个操作数必须是寄存器。 ```asm xchg ecx, edx ; 交换ecx和edx的内容 ``` - **PUSH/POP** `push` 和 `pop` 指令分别用于将数据压入堆栈或将数据弹出堆栈。通常会涉及通用寄存器的操作。 ```asm push eax ; 将eax压入堆栈 pop ebx ; 从堆栈弹出数据至ebx ``` #### 算术运算类指令 这类指令执行基本算术计算,常使用寄存器作为操作数。 - **ADD/SUB** 加法 (`add`) 或减法 (`sub`) 可以直接作用于寄存器或通过寄存器访问内存位置。 ```asm add eax, 1 ; 将eax加1 sub ebx, ecx ; 将ebx减去ecx的值 ``` - **INC/DEC** 增量 (`inc`) 和减量 (`dec`) 操作符专门针对单个寄存器进行自增或自减处理。 ```asm inc esi ; 将esi增加1 dec edi ; 将edi减少1 ``` #### 逻辑运算类指令 此类指令完成按位逻辑运算,同样依赖寄存器来保存中间结果。 - **AND/OR/XOR/NOT** 执行按位逻辑与 (`and`)、或 (`or`)、异或 (`xor`) 和取反 (`not`) 的操作。 ```asm xor eax, eax ; 清零eax(常用技巧) not cl ; 对cl求补码 ``` #### 控制流转移类指令 控制程序流程跳转也经常涉及到寄存器状态的变化。 - **CALL/RET** 调用子过程(`call`) 并返回(`ret`) ,其中调用时可能利用某些特定寄存器如EIP记录下一条待执行指令的位置。 ```asm call my_function; 跳转并调用my_function函数 ret ; 返回至上一调用处 ``` - **JMP/Jcc** 条件跳跃(`jcc`, 如je,jne...) 和无条件跳跃(`jmp`) 都会影响处理器内部标志寄存器的状态从而决定下一步运行哪部分代码片段。 ```asm je label_equal ; 如果相等则跳转到label_equal标签处继续执行 jmp short_label ; 直接跳转到short_label标记的地方 ``` 以上列举了一些典型的关于x86汇编语言里同寄存器紧密关联的基础命令集合[^2]。值得注意的是,在实际开发过程中还存在更多复杂精妙的应用场景等待探索发现。 ```asm section .data msg db 'Hello, world!',0xa ; 字符串定义 len equ $ - msg ; 计算字符串长度 section .text global _start ; 全局入口声明 _start: mov edx,len ; 参数三:消息长度 mov ecx,msg ; 参数二:消息首地址 mov ebx,1 ; 参数一:文件描述符(stdout) mov eax,4 ; 系统调用号(sys_write) int 0x80 ; 中断请求操作系统服务 mov eax,1 ; 准备退出系统调用 xor ebx,ebx ; 设置退出状态为0 int 0x80 ; 请求中断终止进程 ``` 上述例子展示了如何编写一个简单的NASM汇编“Hello World”应用程序[^5]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

随心所欲的小强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值