02.寄存器

寄存器

前言

一个典型的CPU由运算器,控制器,寄存器等器件构成,这些器件靠内部总线连接。简单来说:

  • 运算器进行信息处理
  • 寄存器进行信息存储
  • 控制器控制各种器件进行工作
  • 内部总线连接各种器件,在它们之间进行数据的传送
    对于汇编程序而言,CPU中的主要部件是寄存器,寄存器是CPU中程序员可以进行指令读写的器件,可以通过改写各种寄存器中内容来实现对CPU的控制

不同的CPU,寄存器的个数,结构是不同的。8086CPU有14个寄存器,每个寄存器有一个名称,这些寄存器是:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW

通用寄存器

8086的寄存器都是16位的,可以存放2个字节。AX,BX,CX,DX这4个寄存器通常用来存放一般性数据,被称为通用寄存器
为了兼容性考虑,这四个寄存器又可以拆分成两个独立的寄存器:

  • AX分为AH和AL
  • BX分为BH和BL
  • CX分为CH和CL
  • DX分为DH和DL
    分别表示高8位和低8位

字在寄存器中的存储

出于兼容性的考虑,8086CPU可以处理两种尺寸的数据

  • 字节:byte,由8个bit组成,可以存放8位寄存器中
  • 字:word,由两个byte组成,分别成为高位字节和低位字节

几条汇编指令

汇编语言的书写不区分大小写
在进行数据传送和运算时,要注意指令的两个操作对象的位数应该是一致的

汇编指令 控制CPU完成的操作
mov ax, 18 将18送入寄存器ax中
mov ah, 78 将78送入寄存器ah中
add ax, 8 将寄存器ax中值加上8
mov ax, bx 将寄存器bx中的值送入寄存器ax中
add ax, bx 将ax和bx中值相加,结果存入ax中

以下这些指令是错误的

汇编指令
mov ax, bl
mov bh, ax
mov al, 2000
add al, 100H

物理地址

CPU访问内存时,要给出内存单元的地址,所有的内存单元构成一个一维的线性空间,每一个内存单元都有唯一的地址,我们将这个唯一个地址称之为物理地址
CPU通过地址总线送入存储器的地址必须是一个内存单元的物理地址。在CPU向存储器发送物理地址之前,必须现在内部形成这个地址,不同的CPU可以有不同的地址形成方式

16位结构的CPU

什么是16位结构的CPU
概括来讲,16位的CPU具有以下几方面的结构特性

  • 运算器一次最多处理16位的数据
  • 寄存器的最大宽度为16位
  • 寄存器和存储器之间的通路为16位
    能够一次性处理,传输,暂时存储的信息的最大长度为16位

8086CPU给出物理地址的方法

8086CPU有20位地址总线,可以传送20位地址,寻址能力是 2^20 ;另一方面,它又是16位的CPU结构,按理里说寻址能力为 2^16,它的内部是如何实现的呢?
8086CPU采用了两个16位地址合成一个20位地址的方法:

  • CPU提供两个16位的地址,一个称为段地址,一个称为偏移地址
  • 段地址和偏移地址通过内部总线送入一个称为地址加法器的部件
  • 地址加法器将两个16位地址合成一个20位物理地址
  • 地址加法器通过内部总线将20位物理地址送入输入输出控制电路
  • 输入输出电路将20位物理地址送上地址总线
  • 20位物理地址被地址总线送入存储器
    地址加法器采用 段地址*16+偏移地址的方式生成20位物理地址

段的概念

段的概念不是来自内存,并不是将内存分成一个一个段。段的概念来自于CPU,采用段基址+偏移地址的方式来计算物理地址,使得我们可以通过 段 的形式来管理我们的内存。

段寄存器

CPU采用段基址+偏移地址的方式来计算物理地址,那么是通过什么器件来存储段地址呢?段地址在8086CPU中通过段寄存器存放。8086CPU中有4个段寄存器:CS,DS,SS,ES

CS 和 IP

CS 和 IP 是8086CPU中最为关键的连个寄存器,它们指示了CPU 当前要读取指令的地址。CS 是段寄存器,IP 为指令指针寄存器。
在 8086 PC机上,任何时刻,CPU将读取 CS*16+IP 处的一条指令执行。也可以这样说,8086机中,任意时刻,CPU将CS:IP指向的内容当作指令执行
8086 的 CPU 工作流程简述:

  • 从 CS:IP 指向的内存中读取指令,读取的指令进入指令缓冲器
  • IP = IP + 所读取的指令的长度,从而指向下一条指令
  • 执行指令,转回 步骤1,重复这个过程
    第一节中我们说过,指令和数据没有区别,都是二进制数据,CPU在工作时将有的数据看作指令,有的数据看作数据。那么在什么时候看作指令呢?现在我们明白了,CPU将CS:IP指向的数据看作指令

修改CS,IP的指令

前面提到的通用寄存器,我们可以通过 mov 指令修改其内部的值,mov 指令被称之为 传送指令。

那我们是否可以通过 mov 指令来修改 CS 和 IP 寄存器的值呢?

不能,因为没有提供这样的功能。它提供了另一种类型的指令,能够修改 CS,IP 寄存器值的指令,称之为 转移指令。
先介绍一种最简单的转移指令 jmp

jump 2:0a03 -->同时修改cs和ip的值

单独修改 IP 的值
jump 某一个合法寄存器
jump ax -->将 ax 寄存器中值存入 IP 中

代码段

在编写程序时,可以根据需要,将一组内存单元定义为一个段,我们可以将长度为 N(N <= 64kb)的一段代码,存在一组连续的,起始地址为16倍数的内存单元中,我们可以这样认为,这一段内存就是用来存放代码的,从而定义了一个代码段
运行时,我们只需要指定这段代码段的地址到 cs 和 IP 寄存器中, cpu 就会 从内存中取出相应的指令放入指令缓冲器中执行

课后实验

  • 安装DosBox
  • 使用DosBox进入Debug模式
  • Debug模式下各种command的使用

安装DosBox
使用DosBox进入Debug模式

mount c Dosbox安装地址 --> 将Dosbox 挂载到虚拟的C盘
c: --> 进入 虚拟C盘
debug --> 进入debug模式

其实就是运行 Dosbox 安装路径下的 debug.exe 程序

Debug模式下各种command的使用

  • 使用 R 命令查看,改变CPU寄存器的内容
  • 使用 D 命令查看内存中的命令
  • 使用 E 命令改写内存中的内容
  • 使用 U 命令将内存中机器指令翻译成汇编指令
  • 使用 T 命令执行一条机器指令
  • 使用 A 命令以汇编指令的格式在内存中写入一条机器指令

可以自己在电脑上查找指令的使用方法并实验各种command的功能

参考

<<汇编语言第四版>>-王爽

posted @ 2023-07-31 09:10  异世界穿越中!.!  阅读(72)  评论(0)    收藏  举报