16位汇编语言

16位汇编语言

寄存器

8086CPU有14个寄存器,所有寄存器都是16位的,可以存放2个字节:

  • AX
  • BX
  • CX
  • DX
  • SI
  • DI
  • SP
  • BP
  • CS
  • SS
  • DS
  • ES
  • PSW

这 14 个寄存器有可能进行具体的划分,按照功能可以分为三种:

  • 通用寄存器
  • 段寄存器
  • 控制寄存器

通用寄存器

8086CPU有4个通用寄存器,用来存放一般性的数据:

  • AX(Accumulator Register) :累加寄存器,它主要用于输入/输出和大规模的指令运算。

  • BX(Base Register):基址寄存器,用来存储基础访问地址。

  • CX(Count Register):计数寄存器,CX 寄存器在迭代的操作中会循环计数。

  • DX(Data Register):数据寄存器,它也用于输入/输出操作。它还与 AX 寄存器以及 DX 一起使用,用于涉及大数值的乘法和除法运算。

8086CPU的AXBXCXDX这4个通用寄存器都可以分为两个可独立使用的8位寄存器来用:

寄存器 高位 低位
AX AH AL
BX BH BL
CX CH CL
DX DH DL

除了AXBXCXDX 寄存器以外,其他寄存器均不可以分为两个独立的 8 位寄存器。

寄存器的存储方式是先存储低位,如果低位满足不了就存储高位,如果低位能够满足,高位用 0 补全,在其他低位能满足的情况下,其余位也用 0 补全。

8086 CPU 可以一次存储两种类型的数据:

  • 字节(byte): 一个字节由 8 bit 组成,这是一种恒定不变的存储方式

  • 字(word):字是由指令集或处理器硬件作为单元处理的固定大小的数据,对于 intel 来说,一个字长就是两个字节。

字是计算机一个非常重要的特征,针对不同的指令集架构来说,计算机一次处理的数据也是不同的。也就是说,针对不同指令集的机器,一次能处理不用的字长,有字、双字(32位)、四字(64位)等。

段寄存器

8086CPU有4个段寄存器:

  • CS(Code Segment):代码段寄存器,程序代码的基础位置。
  • DS(Data Segment):数据段寄存器,变量的基本位置。
  • SS(Stack Segment):堆栈段寄存器,栈的基础位置。
  • ES(Extra Segment):附加段寄存器,内存中变量的其他基本位置。

代码段寄存器

  • CS

数据段寄存器

  • DS

8086CPU不支持将数据直接送入段寄存器,需要先将数据送入一个一般的寄存器,如BX,再将BX中的内容送入DS

堆栈段寄存器

  • SS

8086CPU中,有两个寄存器,堆栈段寄存器SS和栈指针寄存器SP,栈顶的段地址存放在SS中,偏移地址存放在SP中。

任意时刻,SS:SP指向栈顶元素。

push指令和pop指令执行时,CPU从SSSP中得到栈顶的地址。

栈顶超界的问题

当栈满的时候,使用push指令入栈,或栈空的时候使用pop指令出栈,都将发生栈顶超界的问题。

8086CPU不保证我们对栈的操作不会越界,8086CPU只知道栈顶在何处(由SS:SP指示),而不知道我们安排的栈空间有多大。

编程时要根据可能用到的最大栈空间,来安排栈的大小,防止入栈的数据太多而导致超界;执行出栈操作的时候也要注意,以防栈空的时候继续出栈而导致的超界。

索引寄存器

索引寄存器主要包含段地址的偏移量,索引寄存器主要分为:

  • BP(Base Pointer):基础指针,它是栈寄存器上的偏移量,用来定位栈上变量。
  • SP(Stack Pointer):栈指针,它是栈寄存器上的偏移量,用来定位栈顶。
  • SI(Source Index):变址寄存器,用来拷贝源字符串。
  • DI(Destination Index):目标变址寄存器,用来复制到目标字符串。

控制寄存器

  • IP(Instruction Pointer):指令指针寄存器,它是从 Code Segment 代码寄存器处的偏移来存储执行的下一条指令.
  • FLAG(EFLAGS Register):标志寄存器用于存储当前进程的状态。

指令指针寄存器

指令指针寄存器(Instruction Pointer)

  • IP

在8086PC机中,任意时刻,设CS中的内容为MIP中的内容为N,8086CPU将从内存M*16+N单元开始,读取一条指令并执行。

也可以这样表述:8086机中,任意时刻,CPU将CS:IP指向的内容当做指令执行。

mov指令不能用于设置CSIP寄存器的值,原因很简单,因为8086CPU没有提供这样的功能。

使用jmp 段地址:偏移地址指令可以同时修改CS:IP寄存器的值:

  • jmp 2AE3:3,执行后:CS=2AE3HIP=0003H,CPU将从2AE33H处读取指令。
  • jmp 3:0B16,执行后:CS=0003HIP=0B16H,CPU将从00B46H处读取指令。

若想仅修改IP寄存器的内容,可用jmp 某一合法寄存器的指令完成,如:

  • jmp ax,指令执行前,ax=1000HCS=2000HIP=0003H 指令执行后,ax=1000HCS=2000HIP=1000H

标志寄存器

FLAG(EFLAGS Register):标志寄存器用于存储当前进程的状态。

标志寄存器,又称程序状态寄存器(它的内容是Program Status Word,PSW)。

这是一个,控制标志和系统标志的寄存器。

标志寄存器EFLAGS中的系统标志和IOPL字段用于控制I/O访问、可屏蔽硬件中断、调试、任务切换以及虚拟8086模式。

FLAG : Flag 寄存器用于存储当前进程的状态,这些状态有:

  • 位置 (Direction):用于数据块的传输方向,是向上传输还是向下传输

  • 中断标志位 (Interrupt) :1 - 允许;0 - 禁止

  • 陷入位 (Trap) :确定每条指令执行完成后,CPU 是否应该停止。1 - 开启,0 - 关闭

  • 进位 (Carry) : 设置最后一个无符号算术运算是否带有进位

  • 溢出 (Overflow) : 设置最后一个有符号运算是否溢出

  • 符号 (Sign) : 如果最后一次算术运算为负,则设置 1 =负,0 =正

  • 零位 (Zero) : 如果最后一次算术运算结果为零,1 = 零

  • 辅助进位 (Aux Carry) :用于第三位到第四位的进位

  • 奇偶校验 (Parity) : 用于奇偶校验

More


16位汇编语言
https://realwujing.github.io/linux/debug/assembly/16位汇编语言/
作者
Wu Jing
发布于
2024年7月23日
许可协议