8086CPU_Learning(1)

16 January 2025
6 mins

搞了那么久的博客现在终于可以开始汇编语言的学习了

这里我用的教材是王爽老师的《汇编语言》,使用的环境是基于DOSBOX的模拟DOS环境

接下来开始正式的学习

今天的内容是 寄存器 和 实验一

寄存器

8086CPU共有14个寄存器,每个寄存器都有对应的名称,他们分别是:

AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW

我们不一次性的对其进行研究,我们在后续对这些寄存器的作用进行一一的讲解

通用寄存器

AX,BX,CX,DX 这四个寄存器用来放一般性的数据,所以被称为通用寄存器

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

为了保证CPU的兼容性,这四个通用寄存器都可以被分为两个可独立使用的八位寄存器:

XL 指的是 XX寄存器的低八位(0-7位),XH 指的是 XX 寄存器的高八位(8-15位)

字在寄存器中的存储

出于对兼容性的考虑,8086CPU可以对以下两种尺寸的数据进行操作:

一个字可以存在一个16位寄存器中,那么这个字的高位字节和低位字节便存储在这个寄存器的高8位寄存器和低8位寄存器中

基本的汇编指令

介绍 mov 与 add

这里我们用几个例子来展示他们的用法

MOV:

ADD:

注意:

  1. 十六位寄存器的溢出:

    当ax = bx = 8226H时,执行 add ax,bx 后ax = ?

    ax本来应该等于 1044CH,但是由于最高位溢出了,所以ax = 044CH

  2. 八位寄存器的溢出:

    当 ax = 00C5H时,执行 add al,93H 后al = ?

    ax本来应该等于 0158H,但是由于最高位溢出了,所以ax = 0058H,al = 58H

8086给出物理地址的方法

所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间都有唯一的地址,我们将这个唯一的地址称为物理地址。在CPU发出物理地址之前,必须要在内部先生成这个地址

8086CPU有20位地址总线,最多可以传20位地址,达到1MB的寻址能力

可是8086是16位机器,按道理只能做到16位的64KB寻址,是怎么做到的呢?

这是因为我们使用了一种通过两个十六位地址合成一个二十位地址的方法

当8086CPU要读写内存时:

在这里地址加法器通过 物理地址 = 段地址*16 + 偏移地址 生成20位的物理地址

注意:段地址*16 本质上就是将段地址左移四位,将地址XXXXH变为XXXX0H

段的概念

在根据编程需要时我们将若干连续的内存单元看作一个段

先讲解一下段的含义,在这里,段并不意味着内存被分为一段一段,而是我们可以通过分段的方式来管理内存

段的划分来源于CPU ,由于我们使用 物理地址 = 段地址*16 + 偏移地址 的方式给出内存的物理地址

所以我们用 段地址*16 定位段的起始地址(基础地址),用偏移地址定位段中的内存单元

我们需要注意:

段寄存器

8086 有四个段寄存器CS、DS、SS、ES,这里我们先只看CS

其中CS,IP 是8086CPU中最重要的两个寄存器,他们指示了CPU当前要读取的指令的地址

CS 为代码段寄存器,IP为指令指针寄存器,我们可以这样理解,在8086机中任意时刻,CPU将CS:IP指向的内容当作指令执行

我们可以把8086CPU的工作过程表述为:

  1. 从 CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲区
  2. IP = IP + 所读取的指令的长度,从而指向下一条指令
  3. 执行指令,并返回步骤(1),重复这个过程

我们可以这么说,内存中的一段信息被CPU执行过,那么他所在的内存单元一定被CS:IP指向过

修改CS、IP指令

8086CPU大部分的寄存器的值都可以通过mov来改变,但是mov不能用于修改CS:IP 的值,mov被称为传送指令

能够修改CS:IP的值的指令通称为转移指令,如简单的jmp指令

第一条指令

在8086CPU加电启动或者复位后(即刚开始工作时),CS和IP被设置为 CS=FFFFH , IP=0000H

即在8086PC机刚启动时,CPU从内存FFFF0H单元中读取指令执行,FFFF0H单元存放着8086PC机开机后执行的第一条命令

实验一:查看CPU和内存,用机器指令和汇编指令编程

使用DEBUG

DEBUG 是 DOS,Windows 都提供的实模式(8086方式)程序的调试工具。可以用它查看CPU的各种寄存器中的内容、内存使用的情况和在机器码级跟踪程序的运行

我们需要用到以下的Debug功能:

R命令

debug -r

开启了debug的R模式

image.png

我们可以看到一个用法 -r 寄存器名称 可以修改指定寄存器的值

D命令

debug -d

我们可以看出其显示的三部分:

其有以下三种用法:

E命令

debug -e

image.png

我们可以通过E指令来进行内存空间的改写,其操作如下:

e 起始地址 数据1 数据2 数据3 …… 这个操作对起始地址之后的内存空间进行覆盖

其中数据可以是字符,也可以是数值,甚至是字符串

或者我们可以使用提问式的方法来进行修改

image.png

有以下步骤:

U指令

我们使用E指令写入以下的一段汲取嘛,然后用U指令对其内容翻译为汇编指令

b80100		mov ax,0001
b90200		mov cx,0002
01c8  		add ax,cx

我们看到D命令的输出可以分为三部分:

T命令

现在我们尝试执行我们写的汇编语言,使用T命令执行一条或多条汇编指令

首先我们需要修改CS:IP 指向的命令 然后开始执行

image.png

我们可以看到执行结果符合我们呢的期望

A命令

前面我们使用E命令写入机器指令,这样很不方便,所以我们使用A指令直接写入指令

其效果如下:

image.png

我们看到再给出起始地址后可以直接进行编辑


← code a TCP/IP(2)

算法小练(1) →