汇编:寄存器

本文最后更新于:2022年11月3日 下午

学习8086CPU中的几个常用寄存器

学习8086CPU中的几个常用寄存器


寄存器

8086CPU 有14个寄存器

  • 通用寄存器:AX, BX, CX, DX
  • 变址寄存器:SI, DI
  • 指针寄存器:SP, BP
  • 指令指针寄存器:IP
  • 段寄存器:CS, SS, DS, ES
  • 标记寄存器:PSW

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

但是上一代的寄存器都是8位的,如8080,8088,如何保证兼容性呢?

可以将通用寄存器分为两个独立的8位寄存器来使用

AX可以分为AHAL, H代表高的意思,L代表低的意思

如果两个8位相加结果进位了,会把高位丢失掉

如上 add al, bl 意思是将 bx的低8位和ax的高8位进行相加,然后将结果存到ax的高8位中

1A + 26 = 40
A + 6 = 16; 16要进1
2+1+1 = 3;

8086CPU的地址总线是20位的,但是寄存器都是16位的,16位的寄存器可寻址空间只有64kb,那肯定是不够的,8086 有一个位址加法器通过用两个寄存器(段地址,偏移地址)合成一个20位的物理地址之后再通过20位的地址总线发送给内存,完成寻址

物理地址=段地址x16 + 偏移地址, (段地址左移一位,再加上偏移地址)

	 1230
	+ 00C8
	-------
	 123C8

// 段地址和偏移地址可以灵活调整 如 123C + 0008
// 216位寄存器有多钟方式来表示20位的地址

516位可以有1M的寻址能力

用分段的方式管理内存

内存并没有分段,段的划分来自于CPU

偏移地址16位,变化范围为0~FFFFH,用偏移地址最多寻址64KB,也就是4个F

例如,给定段地址2000H,用偏移地址寻址的范围是:20000H~2FFFFFH,共64KB

在8086CPU存储单元地址的表示法

例如21F60H内存单元中,段地址是2000H

(a)数据在2000:1F60单元中

(b)数据存在内存的2000段中的1F60单元

段地址很重要

  • CS -
  • DS
  • SS
  • ES

DEBUG

r // 查看
r ax // 修改ax寄存器的内存地址

d 查看内存中的内容
d 2000:0000 查看指定物理地址的内容
d 2000:0 2f 查看指定结束地址的内容

e 2000:0000 12 34 56 3F F3 // 修改指定内存地址中的内容
e 2000 // 回车后采用询问式修改,每次修改完后按空格继续,回车键表示结束
	61 41 // 

// 指定地址的机器码转义成汇编并输出
e 2000:0000 // 先写入一部分内容
u 2000:0000

写入机器码转义成汇编并输出

以上已经可以通修改机器码的方式来修改内存的内容,但是那样又回到了通过机器码编程的时代,可读性很差,还有一种可以通过汇编的方式来往指定地址写入代码,它会自动转换成机器码

比如要像 CS,IP 的这个地址中写入程序
先通过r命令查看一下这俩寄存器的地址
r
a 073f:100 // 回车后开始输入 对应汇编,结束的时候空行回车
u 073f:100 // 查看指定位置内容

执行指令

通过 t 命令执行指令,每次输入t会执行一条指令,每次执行完指令后IP会加1
t 命令会执行 CS+IP地址处的内容,如果要执行其它地址的内容,可以通过r命令来修改CS和IP的地址

CP, IP寄存器

这是两个比较重要的寄存器,CS是代码段寄存器,IP是指令指针寄存器, CS:IP将物理地址中指向的内容当做指令执行

执行过程,当执行完一条指令后,IP要更改,IP=IP+上条所读指令的长度,这个例子中第一条的指令长度为3,所以第一条指令执行完之后,IP=0003

可通过dosbox来进行验证,同时复习debug工具的使用

内存中的数据 D8 23 01 BB 03 00 89 D8 01 D8究竟是用作一般数据,还是用作指令

这取决于程序员是怎么使用它的,CPU会将CS:IP指向的内存单元的内容当做指令来执行

jmp 跳转指令

上述的学习都假设指令是按顺序执行的,但实际的应用程序中,其实是会发生很多分支的,例如if语句,那么汇编就需要通过一种方式来执行这样的操作

在汇编中,是不允许直接对 CSIP赋值地址的,特别是IP寄存器,IP寄存器的操作权始终都是在CPU手里的。

// 下述语法是报错的
mov cs, 2000
mov ip, 0003

mov ax, 2000
mov cs, ax // 语法通过
mov ip, ax // 语法报错,不允许修改ip寄存器

同时修改CS, IP的内容

jmp 2AE3:3
jmp 3:0B16

只修改IP的内容

jmp ax
jmp bx

存储单元

存储器被分为若干个存储单元,

微型机存储器的存储单元可以存储一个Byte(字节), 一个Byte是由8bit(比特)组成的,例如B8 是两个十六进制数,这两个十六进制数就刚好占用了一个存储单元。

因为一个十六进制就需要4bit来表示,两个就需要8bit

一个字需要两个字节来表示,也就是2B,16位

1B=8b
1KB=1024B
1MB=1024KB
1GB=1024MB
1TB=1024GB

总线

CPU的引脚连接着总线,通过3种总线的宽度可以标志这个CPU不同方面的性能

  • 地址总线宽度决定CPU的寻址能力
  • 数据总线宽度决定CPU与其他器件进行数据传送时的传送量
  • 控制总线决定了CPU对系统重其它器件的控制能力

地址总线

CPU 是通过地址总线来指定存储单元的,地址总线越宽,则CPU的可寻址范围就更大。

假设CPU10根地址总线,在电子计算机中,一根导线可以传送的稳定状态只有高电平和低电平两种,对应到二进制就是0110根导线可以传送10位二进制数据,而10位二进制数可以表示2的10次方个。最小数为0,最大数为1023

数据总线

CPU与其它器件之间的数据传送是需要通过数据总线来进行的。数据总线的宽度决定了CPU与外界的数据传送速度,8根数据总线一次可以一个字节(8个二进制数据),16根数据总线一次性可以传送两个字节。

8088CPU的数据总线是8根,8086CPU的数据总线是16根,一次可以传送两个字节

https://view.inews.qq.com/a/20211122A0D1TB00

内存地址空间


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议,转载请注明出处。