汇编:寄存器
本文最后更新于: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
可以分为AH
和AL
, 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
// 2个16位寄存器有多钟方式来表示20位的地址
5
个16
位可以有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
语句,那么汇编就需要通过一种方式来执行这样的操作
在汇编中,是不允许直接对 CS
和IP
赋值地址的,特别是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
是由8
个bit(比特)
组成的,例如B8
是两个十六进制数,这两个十六进制数就刚好占用了一个存储单元。
因为一个十六进制就需要4
个bit
来表示,两个就需要8
个bit
。
一个字需要两个字节来表示,也就是2B,16位
1B=8b
1KB=1024B
1MB=1024KB
1GB=1024MB
1TB=1024GB
总线
CPU
的引脚连接着总线,通过3
种总线的宽度可以标志这个CPU
不同方面的性能
- 地址总线宽度决定
CPU
的寻址能力 - 数据总线宽度决定
CPU
与其他器件进行数据传送时的传送量 - 控制总线决定了
CPU
对系统重其它器件的控制能力
地址总线
CPU 是通过地址总线来指定存储单元的,地址总线越宽,则CPU
的可寻址范围就更大。
假设CPU
有10
根地址总线,在电子计算机中,一根导线可以传送的稳定状态只有高电平和低电平两种,对应到二进制就是0
和1
,10
根导线可以传送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 协议,转载请注明出处。