通用寄存器

本文最后更新于:2023年12月5日 晚上

在汇编世界里,我们主要通过汇编指令来操纵两种东西:

  • 寄存器
  • 内存地址

通用寄存器

寄存器的位数

由于 x86-64 架构惊人的后向兼容性,同一个寄存器,我们可以使用其中的 8bit、16bit、32bit、64bit,以 ax 寄存器为例,分别是 ah/al、ax、eax、rax,如下图所示:

通用寄存器的逻辑结构一定要记住:

这就导致一个问题,从大的寄存器上往小的寄存器上 mov 没有问题,而从小的寄存器往大的寄存器上 mov 就需要使用 movsxd 或者 movsx 指令了:

寄存器有两种概念,逻辑上的和物理上的,分别是架构相关寄存器(architectural register)和物理寄存器(physical register)。前者是指令集(ISA)提供给编译器可见的,相当于 API 接口规范,一共 16 个通用寄存器;后者是硬件上实际设计的,软件领域不直接接触。最新的 CPU 可能有上百个实际的物理寄存器。当然了,对软件开发人员来说,我们只需要关注逻辑上的通用寄存器。

这 16 个逻辑上的通用寄存器如下所示:

寄存器 16bit / 32bit / 64bit 主要用途 编号
ax / eax / rax 累加器 0
cx / ecx / rcx 计数 1
dx / edx / rdx I/O 指针 2
bx / ebx / rbx DS 段的数据指针 3
sp / esp / rsp 堆栈指针寄存器在堆栈操作中使用,PUSH 和 POP 指令是从 SP 寄存器得到现行堆栈段的段内偏移量,所以称 SP 寄存器为堆栈指针:stack pointer,SP 始终指向栈顶。 4
bp / ebp / rbp BP 与 SS 连用,为访问现行堆栈段提供方便。通常 BP 寄存器在间接寻址中使用,操作数在堆栈段中,由 SS 段寄存器和 BP 组合形成操作数的地址,即 BP 中存放现行堆栈段中一个数据区的“基址”的偏移量,所以称 BP 为基址指针:base pointer 5
si / esi / rsi 变址寄存器(IndexRegister),它们主要用于存放存储单元在段内的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。变址寄存器不可分割成 8 位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。它们可作一般的存储器指针使用。在字符串操作指令的执行过程中,对它们有特定的要求,而且还具有特殊的功能。
存储器指针,串指令中的源操作数指针:source indexRegister
6
di / edi / rdi 存储器指针,串指令中的目的操作数指针:destination indexRegister 7
r8
r9
r10
r11
r12
r13
r14
r15

编号一定要记住,后面有用

汇编就是在“寄存器与寄存器”或者“寄存器与内存”之间来回移动数据。

寄存器和内存编号(内存地址)的区别

没有区别,唯一的区别就是前者位于 cpu,后者位于内存

每个寄存器指向 16/32/64 位的空间

每个内存编号指向 8 位的空间,这也就是为什么说操作内存的最小单位是字节

常用指令

MOV 指令

MOV DST,SRC   ; DST:目标操作数  SRC:源操作数

MOV r/m8,r8    r 通用寄存器
MOV r/m16,r16   m 代表内存
MOV r/m32,r32   imm 代表立即数
MOV r8,r/m8    r8 代表8位通用寄存器
MOV r16,r/m16   m8 代表8位内存
MOV r32,r/m32   imm8 代表8位立即数
MOV r8, imm8
MOV r16, imm16
MOV r32, imm32

作用:拷贝源操作数到目标操作数

  1. 源操作数可以是立即数、通用寄存器、段寄存器、或者内存单元.
  2. 目标操作数可以是通用寄存器、段寄存器或者内存单元.
  3. 操作数的宽度必须一样.
  4. 源操作数和目标操作数不能同时为内存单元.

ADD 指令

ADD DST,SRC   ; DST:目标操作数  SRC:源操作数

ADD AL, imm8
ADD AX, imm16
ADD EAX, imm32
ADD r/m8, imm8
ADD r/m16,imm16
ADD r/m32,imm32
ADD r/m16, imm8
ADD r/m32, imm8
ADD r/m8, r8
ADD r/m16, r16
ADD r/m32, r32
ADD r8, r/m8
ADD r16, r/m16
ADD r32, r/m32

作用:目标操作数与源操作数相加,将结果存回目标操作数

示例:

mov eax,1
mov ebx,2
add eax,ebx  ; eax = 3

SUB 指令

SUB DST,SRC

SUB AL, imm8
SUB AX, imm16
SUB EAX, imm32
SUB r/m8, imm8
SUB r/m16,imm16
SUB r/m32,imm32
SUB r/m16, imm8
SUB r/m32, imm8
SUB r/m8, r8
SUB r/m16, r16
SUB r/m32, r32
SUB r8, r/m8
SUB r16, r/m16
SUB r32, r/m32

作用:目标操作数减去源操作数,将结果存回目标操作数

示例:

mov eax,3
mov ebx,1
sub eax,ebx  ; eax = 2

AND 指令

AND DST,SRC

AND AL, imm8
AND AX, imm16
AND EAX, imm32
AND r/m8, imm8
AND r/m16,imm16
AND r/m32,imm32
AND r/m16, imm8
AND r/m32, imm8
AND r/m8, r8
AND r/m16, r16
AND r/m32, r32
AND r8, r/m8
AND r16, r/m16
AND r32, r/m32

作用:目标操作数和源操作数按位逻辑与操作,将结果存回目标操作数

示例:

mov eax,111  ; eax = 0x00000111 = 0000000000000000000000000000000111
mov ebx,101  ; ebx = 0x00000101 = 0000000000000000000000000000000101
and eax,ebx  ; eax = 0x00000101

OR 指令

OR DST,SRC

OR AL, imm8
OR AX, imm16
OR EAX, imm32
OR r/m8, imm8
OR r/m16,imm16
OR r/m32,imm32
OR r/m16, imm8
OR r/m32, imm8
OR r/m8, r8
OR r/m16, r16
OR r/m32, r32
OR r8, r/m8
OR r16, r/m16
OR r32, r/m32

作用:DST 和 SRC 按位逻辑或操作,将结果存回 DST

示例:

mov eax,100
mov ebx,1
or eax,ebx  ; eax = 0x00000101

XOR 指令

XOR DST,SRC

XOR AL, imm8
XOR AX, imm16
XOR EAX, imm32
XOR r/m8, imm8
XOR r/m16,imm16
XOR r/m32,imm32
XOR r/m16, imm8
XOR r/m32, imm8
XOR r/m8, r8
XOR r/m16, r16
XOR r/m32, r32
XOR r8, r/m8
XOR r16, r/m16
XOR r32, r/m32

作用:DST 和 SRC 按位逻辑异或操作,将结果存回 DST。异或是不同则真

示例:

mov eax,101
mov ebx,1
xor eax,ebx  ; eax = 0x00000100

NOT 指令

not DST

NOT r/m8
NOT r/m16
NOT r/m32

作用:对 DST 按位取反,将结果存回 DST

示例:

mov eax,ffffffff
mov [56fee4],eax    ; [56fee4] = 0xffffffff
not eax       ; eax = 0x00000000
not dword ptr ds:[56fee4]  ; [56fee4] = 0x00000000

LEA

Load Effective Address:加载有效地址,将源操作数的地址加载到目的寄存器中

MOV 指令可以通过内存地址读取数据,如果只是需要内存地址,就可以使用 LEA 指令


通用寄存器
http://blog.lujinkai.cn/汇编/通用寄存器/
作者
像方便面一样的男子
发布于
2022年9月24日
更新于
2023年12月5日
许可协议