本文主要将介绍的是8086 CPU中的寄存器
寄存器就是个存储信息的单元或者说是器件又或者说是容器而已,就比如内存也是一个存储介质或者说是存储单元而已,其实寄存器从理解上来说和内存差不多,
只不过寄存器(这里讨论的寄存器都是 CPU 中的寄存器,不包括外设上的寄存器)位于CPU内部,寄存器是 CPU 中的稀有资源,而对于一个汇编程序员来说,CPU 中主要可以使用的也就是寄存器而已,汇编程序员可以使用指令来读写 CPU 中的寄存器,从而可以实现对于 CPU 的控制,当然,不同的 CPU ,寄存器的个数和结构都是不一样的,比如 8086 CPU 中,寄存器的个数也就 14 个而已,并且 8086 CPU 中所有的寄存器的结构为 16 位,即一个寄存器中可以存放下2B即2个字节,而到了 80386 CPU 中,寄存器的个数也比 8086 增多了。
8086 CPU 中寄存器总共为 14 个,且均为 16 位 。
即 AX,BX,CX,DX,SP,BP,SI,DI,IP,FLAG,CS,DS,SS,ES 共 14 个。
而这 14 个寄存器按照一定方式又分为了通用寄存器,控制寄存器和段寄存器。
通用寄存器:
AX,BX,CX,DX 称作为数据寄存器:
AX (Accumulator):累加寄存器,也称之为累加器;
BX (Base):基地址寄存器;
CX (Count):计数器寄存器;
DX (Data):数据寄存器;
SP 和 BP 又称作为指针寄存器:
SP (Stack Pointer):堆栈指针寄存器;
BP (Base Pointer):基指针寄存器;
SI 和 DI 又称作为变址寄存器:
SI (Source Index):源变址寄存器;
DI (Destination Index):目的变址寄存器;
控制寄存器:
IP (Instruction Pointer):指令指针寄存器;
FLAG:标志寄存器;
段寄存器:
CS (Code Segment):代码段寄存器;
DS (Data Segment):数据段寄存器;
SS (Stack Segment):堆栈段寄存器;
ES (Extra Segment):附加段寄存器;
通用寄存器
从上面可以知道,在 8086 CPU 中,通用寄存器有 8 个,分别是 AX,BX,CX,DX,SP,BP,SI,DI ,
至于为什么给它们取名做通用寄存器,那是因为,这些个寄存器每一个都有自己专门的用途,
比如 CX 作为计数寄存器,则是在使用 LOOP 指令循环时用来指定循环次数的寄存器,
如果它们每一个都只有一个专用的作用,那就它们只能称之为专用寄存器了,
正是因为这些个寄存器还可以用来传送数据和暂存数据,所以才称它们为通用寄存器 。
下面就按顺序来一一介绍这几个通用寄存器了:
数据寄存器(AX,BX,CX,DX):
数据寄存器有 AX,BX,CX,DX 四个组成,由于在 8086 之前的 CPU 为 8 位 CPU,所以为了兼容以前的 8 位程序,在 8086 CPU 中,每一个数据寄存器都可以当做两个单独的寄存器来使用,由此,每一个 16 位寄存器就可以当做 2 个独立的 8 位寄存器来使用了 。
AX 寄存器可以分为两个独立的 8 位的 AH 和 AL 寄存器;
BX 寄存器可以分为两个独立的 8 位的 BH 和 BL 寄存器;
CX 寄存器可以分为两个独立的 8 位的 CH 和 CL 寄存器;
DX 寄存器可以分为两个独立的 8 位的 DH 和 DL 寄存器;
除了上面 4 个数据寄存器以外,其他寄存器均不可以分为两个独立的 8 位寄存器 ;
注意在上面标志中的“独立”二字,这两个字表明 AH 和 AL 作为 8 位寄存器使用时,
可以看做它们是互不相关的,也就是看做两个完全没有联系的寄存器 X 和 Y 即可,
AX 寄存器:
AX 的另外一个名字叫做累加寄存器或者简称为累加器,其可以分为 2 个独立的 8 位寄存器 AH 和 AL;在写汇编程序时,AX 寄存器可以说是使用率最高的寄存器,
既然 AX 是数据寄存器的话,那么理所当然,其可以用来存放普通的数据。
BX 寄存器:
首先可以明确的是,BX 作为数据寄存器,表明其是可以暂存一般的数据,除了暂存一般性数据的功能外,BX 作为通用寄存器的一种,BX 主要还是用于其专属功能 – 寻址(寻址物理内存地址)上,BX 寄存器中存放的数据一般是用来作为偏移地址使用的。
CX 寄存器:
CX 寄存器作为数据寄存器的一种,其同样具有和 AX,BX 一样的特点,即可以暂存一般性的数据,CX 也是有其专门的用途的,CX 中的 C 被翻译为 Counting 也就是计数器的功能,当在汇编指令中使用循环 LOOP 指令时,可以通过 CX 来指定需要循环的次数,而 CPU 在每一次执行 LOOP 指令的时候,都会做两件事:
一件就是令 CX = CX – 1,即令 CX 计数器自动减去 1;还有一件就是判断 CX 中的值,如果 CX 中的值为 0 则会跳出循环,而继续执行循环下面的指令,
当然如果 CX 中的值不为 0 ,则会继续执行循环中所指定的指令 。
DX 寄存器:
DX 寄存器作为数据寄存器的一种,同样具有和 AX,BX,CX 一样的特点,即可以暂存一般性的数据
8086 CPU访问物理地址的方法
8086相关部件的逻辑结构:
地址加法器采用:物理地址=段地址 * 16 + 偏移地址 的方法计算物理地址
8086cpu的工作过程可以简单描述如下:
(1)从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器
(2)IP=IP+所读的指令的长度,从而指向下一条指令
(3)执行指令,转到步骤(1),重复这个过程
实验
查看cpu和内存,用机器指令和汇编指令编程
1、预备知识-Debug的使用
Debug是一个DOS实用程序,是供程序员使用的程序调试工具,可以用它检查内存中任何地方的字节以及修改任何地方的字节。它可以用于逐指令执行某个程序以验证程序运行的正确性,也可以追踪执行过程、比较一个指令执行前后的值以及比较与移动内存中数据的范围,读写文件与磁盘扇区。
debug的命令较多,有20多个,这里将使用到的一些Debug命令的解释如下:
-R:查看、改变CPU寄存器的内容
-D:查看内存中的内容
-E:改写内存中的内容
-U:将内存中的机器指令翻译成汇编指令
-T:执行一条机器指令
-A:以汇编指令的格式在内存中写入一条机器指令
在【开始】菜单中的【运行】对话框,输入”cmd”回车,可以使用ALT+ENTER将窗口转变为全屏
输入debug命令
(1)使用R命令查看、改变CPU寄存器的内容
注意CS和IP的值,CS=1388,IP=0100,即内存1388:0100处的指令为CPU当前要读取、执行的指令
(2)使用D命令查看内存中的内容
d 段地址:偏移地址 debug将列出从指定内存单元开始的128个内存单元的内容
还可以用指定D命令的查看范围,此时采用”d段地址:起始偏移地址 结尾偏移地址”的格式
比如要看1000:0–1000:9中的内容
(3)使用E命令改写内存中的内容
用E命令向内存中写入机器码:
用U命令查看内存中机器码的含义:
用T命令执行内存中的机器码:
使用t命令继续执行:
用A命令在内存中写入机器指令:
上面使用E命令写入机器指令,不是很方便,最好能直接以汇编指令的形式写入指令,于是出现了下面的A命令:
用A命令向从1000:0开始的内存单元中写入指令
实验任务
(1)使用debug,将下面的程序段写入内存,逐条执行,观察每条指令执行后,CPU中相关寄存器中内容的变化
参考资料
《汇编语言》–王爽
Comments