汇编语言学习(二)——寄存器
目录
一、通用寄存器
二、数据存储
三、汇编指令
四、物理地址
五 、段寄存器
一、通用寄存器
在8086 CPU中,通用寄存器共有四个,分别是 AX、BX、CX 和 DX,它们通常用于存放一般性的数据,均为 16 位寄存器,可以存储两个字节的数据。
1、AX :常用于数据中转和算术运算。它还可以作为累加器(Accumulator),在乘法、除法等操作中发挥重要作用。
2、BX:通常用作基址寄存器,用于间接寻址,即在内存地址中作为偏移量的一部分。
3、CX:通常用作计数器寄存器(Count Register),在循环操作和字符串操作中非常有用。
4、DX:通常用作数据寄存器,用于存储数据或 I/O 端口地址。
通用寄存器 | AX | BX | CX | DX |
用途 | 1.输入/输出操作(如 I/O 指令); 2.用于乘法和除法操作; 3.作为默认的寄存器用于数据传递和运算; | 1.用于存储偏移地址,配合段寄存器(如 DS)形成完整的内存地址; 2.用于数组访问和间接寻址; | 1.用于循环指令(如 2.用于字符串操作中的重复操作(如 | 1.用于存储 I/O 端口地址,例如在 2.用于乘法和除法操作,与 AX 配合使用 |
细化 | AH、AL | BH、BL | CH、CL | DH、DL |
通用寄存器均可分为两个独立的8位寄存器使用;
AH/BH/CH/DH:用于存放高8位地址;
AL/BL/CL/DL:用于存放低8位地址;
二、数据存储
8086CPU一次性可以处理两种尺寸的数据:
- 字节(byte):一个字节由8个bit组成,可以存在8位寄存器中;
- 字(word):一个字节由两个字节组成;
- 这个字的高位字节存在这个寄存器的高8位寄存器;
- 这个字的低位字节存在这个寄存器的低8位寄存器;
-
三、汇编指令
主要对add和mov指令进行介绍。
1、mov指令:用于将数据从一个操作数复制到另一个操作数。它是最常用的指令之一,主要用于数据的传递和初始化。MOV
指令可以操作寄存器、内存单元和立即数(常量)。
基本格式:
MOV destination, source
其中:destination 是目标操作数,可以是寄存器、内存单元或段寄存器;source 是源操作数,可以是寄存器、内存单元或立即数;
支持的操作数类型
寄存器与寄存器:如 MOV AX, BX。
寄存器与内存:如 MOV AX, [0100H]。
寄存器与立即数:如 MOV AX, 1234H。
内存与寄存器:如 MOV [0100H], AX。
内存与立即数:如 MOV [0100H], 5678H。
段寄存器与寄存器:如 MOV DS, AX。
段寄存器与立即数:如 MOV DS, 2000H。
注意事项
MOV指令不能同时操作两个内存地址(如 MOV [0100H], [0200H] 是非法的)。
MOV 指令不能将立即数直接传给段寄存器(如 MOV DS, 1234H 是非法的)。
MOV 指令不能将立即数作为目的操作数(如 MOV 1234H, AX 是非法的)。
MOV 指令不会影响任何标志位(Flags)。
2、ADD指令:用于将两个操作数相加,并将结果存回第一个操作数。它主要用于算术运算,如加法操作。ADD指令会修改标志位(如进位标志 CF、零标志 ZF、符号标志 SF 等)。
基本格式:
ADD destination, source
其中:destination 是目标操作数,可以是寄存器或内存单元;source 是源操作数,可以是寄存器或内存单元;
支持的操作数类型
寄存器与寄存器:如 ADD AX, BX。
寄存器与内存:如 ADD AX, [0100H]。
内存与寄存器:如 ADD [0100H], AX。
内存与内存:如 ADD [0100H], [0200H]
注意事项
ADD 指令不能同时操作两个内存地址(如 ADD [0100H], [0200H] 是非法的)。
ADD 指令不能将立即数作为源操作数(如 ADD AX, 1234H 是非法的)。
ADD 指令会修改标志位(如进位标志 CF、零标志 ZF、符号标志 SF 等)。
注意:
指令的两个操作对象的位数要一致;
当加法溢出时,高位会被舍弃;
四、物理地址
每一个内存单元在空间中都由唯一的地址,这个唯一的地址称为物理地址。
8086有20根地址总线,寻址能力为2^20(1M);
8086的运算器最多一次可以处理16位数据,采用两个16位地址(段地址、偏移地址)合成一个20位的物理地址;
地址加法器合成物理地址的方式:
物理地址 = 段地址 * 16 + 偏移地址;
这三种方式都可以表示物理地址:123C8(CPU可以用不同的段地址偏移地址形成同一个物理地址);
“段地址×16+偏移地址=物理地址”的本质含义:CPU在访问内存时,用一个基础地址(段 地址×16)和一个相对于基础地址的偏移 地址相加,给出内存单元的物理地址。
偏移地址16位,变化范围为0~FFFFH,仅用偏移地址来寻址最多可寻64KB个内存单元。
CS:IP
计算出物理地址,从内存中读取指令。
IP
的值,使其指向下一个要执行的指令。
CS:IP
是一种 逻辑地址 ,而物理地址是通过 CS × 16 + IP
计算得出的;
CS:IP
用于确定程序的执行流程,是程序跳转、函数调用等操作的基础;
CS
和 IP
,可以实现程序的跳转、中断处理等操作。 section .datadata db 12H, 34H, 56H, 78H ; 定义一个字节数组section .textglobal _start_start:mov bx, .data ; 将数据段地址赋给 BXmov ds, bx ; 将 BX 的值赋给 DSmov al, [0] ; 从 DS:0 读取一个字节到 ALmov ah, 0x00 ; 设置 AH 为 0,表示输出一个字符mov dl, al ; 将 AL 的值赋给 DLint 0x80 ; 调用系统调用输出字符
注意事项:
不能直接赋值给 DS:8086 汇编语言不允许直接将段地址赋给 DS,必须通过通用寄存器(如 BX)进行中转。
区分字节和字:一个字由两个字节组成,高位字节存储在低地址单元,低位字节存储在高地址单元。例如,[0]
表示一个字节,[0]
和 [1]
表示一个字。
默认段地址:在程序开始时,DS 的默认值为 0,因此需要手动赋值。
(3)SS:SP
定义:
SS:用于存放堆栈段的段地址;
SP:用于存放堆栈顶元素的偏移地址;
用途:SP 与 SS 结合,用于确定堆栈顶元素的物理地址。在堆栈操作中,SP 会随着 PUSH
和 POP
指令的执行而自动变化。
SS:SP 的作用:
指向栈顶元素:任意时刻,SS:SP
指向当前堆栈顶元素的物理地址。
入栈操作(PUSH):
SP = SP - 2
:SP 先减 2,以确保下一个入栈操作的地址正确。
将数据写入 SS:SP
指向的内存单元。
出栈操作(POP):
从 SS:SP
指向的内存单元读取数据。
SP = SP + 2
:SP 先加 2,以指向下一个栈顶元素。
注意事项:
只能操作字(16 位) :8086 CPU 的堆栈操作是以字为单位进行的,不能直接操作字节(8 位)。
堆栈增长方向:堆栈是向下增长的,即每次入栈时,SP 会减小,出栈时 SP 会增大。
(4)ES:DI
定义:
ES:用于存放额外数据段的段地址。它通常用于访问与程序主数据段(DS)分离但需要频繁访问的数据,例如字符串、数组等。
DI:用于存放目标地址的偏移量。
ES 与 DI 寄存器结合,用于指定目标地址。