王爽「汇编语言」学习笔记(二)

Study Notes Assembly

通用寄存器

8086CPU 的所有寄存器都是 16 位的,可以存放 2 字节的数据。

8086CPU 一共有 14 个寄存器,分别是:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW,其中 AX,BX,CX,DX 通常用来存放一般性的数据,称为通用寄存器。

为了兼容上一代的 8 位寄存器,8086 的这四个通用寄存器都可以拆分成两个独立的寄存器来使用,如 AH、AL 。

字在寄存器中的存储

8086CPU 可以一次性处理一下两种尺寸的数据:

  1. 字节:8 位,可以存放在 8 位寄存器中
  2. 字:16 位,可以存放在 16 位寄存器中,高位字节和地位字节分别存放在该 16 位寄存器的高 8 位寄存器与低 8 位寄存器中

几条汇编指令

汇编指令 控制 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 + B

指令中的数值也可以用 16 进制数表示,只需在后面加上 H 表示即可。

在进行数据传送和运算时,注意指令的两个操作对象的位数应当是一致的。

物理地址

所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,即物理地址。

CPU 向地址总线发出物理地址之前,必须先在内部形成这个物理地址。

不同的 CPU 可以有不同的形成物理地址的方式。

16 位结构的 CPU

16 位结构描述了一个 CPU 具有下面几方面的结构特性:

  • 运算器一次最多可以处理 16 位的数据
  • 寄存器的最大宽度为 16 位
  • 寄存器和运算器之间的通路为 16 位

8086CPU 给出物理地址的方法

8086CPU 的地址总线为 20 位,可以达到 1MB 的寻址能力,但是又是 16 位结构,表现出的寻址能力只有 64KB ,因此 8086CPU 采用一种用两个 16 位地址合成的方法形成一个 20 位的物理地址:物理地址 = 段地址 X 16 + 偏移地址

段地址

在编程时可以根据需要,将若干地址连续的内存单元看作一个段,一个段的起始地址一定是 16 的倍数,长度最大为 64KB 。

段寄存器

段地址在 8086CPU 的段寄存器中存放,8086CPU 有 4 个寄存器:CS、DS、SS、ES 。

CS 和 IP

CS 为代码段寄存器,IP 为指令指针寄存器。

8086 机中,任意时刻,CPU 将 CS:IP 指向的内容当做指令执行,它的工作过程可以简要描述如下:

  1. 从 CS:IP 指向的内存单元读取指令,读取的指令进入指令缓冲器
  2. IP = IP + 所读取的指令的长度,从而指向下一条指令
  3. 执行指令。然后转到步骤 1 重复过程

在 8086PC 刚启动时,CS 和 IP 设置为 CS = FFFFH, IP = 0000H ,所以 FFFF0H 是 8086PC 开机后执行的第一条指令。

CPU 将 CS:IP 指向的内存单元中的内容看作指令。

修改 CS、IP 的指令

8086CPU 大部分寄存器的值都可以用 mov 指令来改变,mov 指令被称为传送指令。

mov 指令不能用于设置 CS、IP 的值。

能够改变 CS、IP 的内容的指令被统称为转移指令,其中最简单的一个为 jmp

若想同时修改 CS、IP ,可以用 jmp 段地址:偏移地址

若想仅修改 IP ,可以用 jmp 某一合法的寄存器

代码段

我们可以将长度为 N 的一组代码存在一组地址连续、起始地址为 16 的倍数的内存单元中,我们认为这段内存是用来存放代码的,从而定义了一个代码段。

CPU 只认被 CS:IP 指向的内存单元中的内容为指令,所以要让 CPU 执行代码段中的指令,必须要将 CS:IP 指向所定义的代码段中的第一条指令的首地址。

实验任务

任务一

第一步先把 CS:IP 指向 1000:0000 ,之后将指令输入到以 1000:0000 为起点的地址中。

先使用 E 命令写入,但是写满一行后发现不能继续输入了,同时用 D 命令查看,发现只成功写入了输入的一部分指令,之后改用 A 命令写入,注意指令的 16 进制数值不需要在末尾加 H 。

然后就是不断使用 T 命令执行了,在这个过程中可以发现寄存器中数值溢出时是直接舍去溢出部分的数,而未溢出部分的数不变,同时低 8 位寄存器溢出也是直接抛弃溢出部分的数,而不是存入高 8 位寄存器中。

任务二

使用 A 命令写入之后将 CS:IP 指向 2000:0 。

这 3 条指令的含义就是首先将 AX 赋值为 1 ,然后不断乘以 2 ,要计算 282^8 的话,只需一直执行 T 命令直到 AX 变为 0100 即可。

任务三

使用 D 命令查看 FFF00H ~ FFFFFH 的内容,发现 FFFF5H ~ FFFFCH 对应的 ASCII 码为 01/01/92 ,推测此为生产日期,表示该主板在 1992 年 1 月 1 日生产。

尝试使用 E 命令改变它 ,结果改变失败,毕竟是写在 ROM 上的嘛

忽略我个 sb 一开始用的 D 命令修改的地方

任务四

直接照搬书上的命令,然后发现更改失败 XD ,这大概又是一个 ROM 吧(

Author: f1a3h

Permalink: https://blog.rbkou.me/Study-Notes/Assembly/asm2/

文章默认使用 CC BY-NC-SA 4.0 协议进行许可,使用时请注意遵守协议。

Comments