-
-
《汇编语言》笔记-寄存器
-
发表于: 2024-10-22 00:11 1959
-
## 通用寄存器
8086CPU的所有的寄存器都是16位的,可以存放两个字节。AX、BX、CX、DX这4个寄存器为通用寄存器。
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729327342491-fecd6767-1e63-4e02-ad05-a099f540fc97.png)
一个16位寄存器可以存储一个16位的数据。
8086CPU的上一代CPU中的寄存器都是8位,为了保证兼容,使原来基于上代CPU编写的程序稍加修改就可以运行在8086之上
8086CPU的 AX、BX、CX、DX、这4个寄存器可以分为两个独立使用的8位寄存器来用
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729327466078-89bf5a32-b3a8-46e5-bb80-03a17b01281d.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729327486596-247b7bd3-9758-422b-8810-20c7b6e36ed0.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729327497048-d30bbae1-4d51-43c1-8524-fd0d60e8e02d.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729327510059-db7e84ce-0d48-4b93-b8aa-65209ed3c718.png)
## 字在寄存器中的存储
8086CPU可以一次性处理以下两种尺寸的数据
+ 字节:byte,一个字节由8个bit组成,可以存在8位寄存器中
+ 字:word,一个字由两个字节组成,两个字节分别称为这个字的高位字节和低位字节
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729327825921-d0ae35f7-6648-45c7-8dc9-f0b93187ae0f.png)
## 汇编指令
| 汇编指令 | CPU操作 | 高级语言 |
| --- | --- | --- |
| mov ax,18 | 将18送入寄存器AX | AX=18 |
| mov ah,78 | 将78送入寄存器AH | AH=78 |
| add ax,8 | 将寄存器AX中的数值加上8 | AX=AX+8 |
| mov ax,bx | 将寄存器BX中的数据送入寄存器AX | AX=BX |
| add ax,bx | 将AX和BX中的数值相加,结果存在AX中 | AX=AX+BX |
程序段指令执行情况 (原AX的值:0000H 原BX的值:0000H)
| 程序段中的指令 | 指令执行后AX中的数据 | 指令执行后BX中的数据 |
| --- | --- | --- |
| mov ax,4E20H | 4E20H | 0000H |
| add ax,1406H | 6226H | 0000H |
| mov bx,2000H | 6226H | 2000H |
| add ax,bx | 8226H | 2000H |
| mov bx,ax | 8226H | 8226H |
| add ax,bx | 044CH | 8226H |
程序段中的最后一条指令 add ax,bx,在执行前 ax和 bx 中的数据都为 8226H,相加后所得的值为:1044CH,但是 ax 为 16 位寄存器,只能存放 4位十六进制的数据,所以最高位的 1不能在 ax 中保存,ax中的数据为:044CH。
程序段指令执行情况 (原AX的值:0000H 原BX的值:0000H)
| 程序段中的指令 | 指令执行后AX中的数据 | 指令执行后BX中的数据 |
| --- | --- | --- |
| mov ax,001AH | 001AH | 0000H |
| mov bx,0026H | 001AH | 0026H |
| add al.bl | 0040H | 0026H |
| add ah,bl | 2640H | 0026H |
| add bh,al | 2640H | 4026H |
| mov ah,0 | 0040H | 4026H |
| add al,85H | 00C5H | 4026H |
| add al,93H | 0058H | 4026H |
程序段中的最后一条指令 add al,93H,在执行前,al 中的数据为 C5H,相加后所得的值为:158H,但是 a1为8位寄存器,只能存放两位十六进制的数据,所以最高位的1丢失,ax 中的数据为:0058H。
## 段地址x16+偏移地址=物理地址 本质含义
“段地址x16+偏移地址=物理地址”的本质含义是:CPU 在访问内存时,用一个基础地址(段地址x16)和一个相对于基础地址的偏移地址相加,给出内存单元的物理地址。
“基础地址+偏移地址=物理地址”的思想
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729329070774-15d9ae10-c4ab-4c71-9d57-93a7460adab2.png)
你要去图书馆,问我那里的地址,我可以用两种方式告诉你图书馆的地址:
(1)从学校走 2826m 到图书馆。这 2826m 可以认为是图书馆的物理地址。
(2)从学校走 2000m 到体育馆,从体育馆再走 826m 到图书馆。第一个距离 2000m,是相对于起点的基础地址,第二个距离 826m 是相对于基础地址的偏移地址(以基础地址为起点的地址)。
第一种方式是直接给出物理地址 2826m,而第二种方式是用基础地址和偏移地址相加来得到物理地址的。
第二个比喻进一步说明“段地址x16+偏移地址=物理地址”的思想。
比如,只能通过纸条来互相通信,你问我图书馆的地址我只能将它写在纸上告诉你。显然,我必须有一张可以容纳4位数据的纸条,才能写下 2826 这个数据。
可不巧的是,我没有能容纳4位数据的纸条,仅有两张可以容纳3位数据的纸条。这样我只能以这种方式告诉你 2826 这个数据。
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729329376351-5f05e024-79ed-4cd3-acca-31ead9ad6cc8.png)
在第一张纸上写上 200(段地址),在第二张纸上写上 826(偏移地址)。假设我们事前对这种情况又有过相关的约定:你得到这两张纸后,做这样的运算:200(段地址)x10+826(偏移地址)=2826(物理地址)。
8086CPU 就是这样一个只能提供两张3位数据纸条的CPU。
## 段的概念
内存并没有分段,段的划分来自于CPU,由于 8086CPU 用“基础地址(段地址x16)+偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理内存。
可以认为:地址10000H~100FFH 的内存单元组成一个段,该段的起始地址(基础地址)为10000H,段地址为1000H,大小为100H;我们也可以认为地址 10000H~1007FH、10080H~100FFH 的内存单元组成两个段,它们的起始地址(基础地址)为:10000H和10080H,段地址为:1000H和1008H,大小都为80H。
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729329483179-a7528744-be6d-419b-a7eb-f35416668908.png)
## 段寄存器
段地址在 8086CPU 的段寄存器中存放。8086CPU有4个段寄存器:CS、DS、SS、ES。当8086CPU要访问内存时由这4个段寄存器提供内存单元的段地址。
## CS和IP
CS为代码段寄存器 IP为指令指针寄存器
在 8086PC 机中,任意时刻,设CS 中的内容为 M,P 中的内容为N,8086CPU 将从内存 Mx16+N 单元开始,读取一条指令并执行。
执行指令工作原理
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331031208-26bea7eb-44ff-42c8-909d-0d931d3e23ac.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331049153-36269334-99ef-4e81-a3a6-0c61ba6f6aac.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331062248-e8c2b9dd-0cb9-4810-9e63-2e1d0cb53310.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331068484-190704ea-2224-4ab4-93a4-0fd7de1e584b.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331074526-c78be36d-62ae-4d10-8354-b4d42ac1c87e.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331082608-546a384e-f179-475a-bd8e-77e362a7c839.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331096954-f215af4b-b8f5-4b0d-a85e-a9fffbea58b7.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331103215-500b569d-3c9a-459e-bee5-b571d0fd215b.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331109103-af34c4e5-ecc5-49ca-9540-5a7a7bb2638f.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331114518-825d90e4-e684-46c6-adab-4ffc3aa6d090.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331123631-3bbaf450-b761-4d40-acba-e8789fe4cf56.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331144730-eea7b600-3d5b-4c22-bc4f-efb66f500c9a.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331152621-0ec51711-a5d5-4d87-8d4c-15151563bc29.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331160485-12a19278-ae9b-4527-a5b8-d22adaccd490.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331168914-126d57a8-3c8c-43b9-a533-97b19d5ae742.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331173722-8fd0a758-8473-4dec-b8ed-4ea522bb7e62.png)
![](https://cdn.nlark.com/yuque/0/2024/png/29236234/1729331179437-9407b681-a73d-4d98-bfb9-f63f9ca22419.png)
## 修改CS、IP指令
jmp指令
同时修改CS IP的内容,可以使用 jmp段地址:偏移地址的指令完成
| jmp 2AE3:3 | CS=2AE3H,IP=0003H | CPU将从2AE33H处读取指令 |
| --- | --- | --- |
| jmp 3:0B16 | CS=0003H,IP=0B16H | CPU将从00B46HH处读取指令 |
只下IP的内容
| jmp ax | |
| --- | --- |
| 执行前 | ax=1000H,CS=2000H,IP=0003H |
| 执行后 | ax=1000H,CS=2000H,IP=1000H |
| jmp bx | |
| 执行前 | bx=0B16H,CS=2000H,IP=0003H |
| 执行后 | bx=0B16H,CS=2000H,IP=0B16H |