0%

被迫自学汇编语言

《汇编语言(第四版)》 . 王爽著 . 清华大学出版社 . 2019

汇编语言实验合集

汇编语言实验合集

实验 1 查看 CPU 和内存,用机器指令和汇编指令编程
实验 2 用机器指令和汇编指令编程
实验 3 编程、编译、连接、跟踪
实验 4 [bx] 和 loop 的使用
实验 5 编写、调试具有多个段的程序
实验 6 实践课程中的程序
实验 7 寻址方式在结构化数据访问中的应用
实验 8 分析一个奇怪的程序
实验 9 根据材料编程
实验 10 编写子程序
课程设计 1
实验 11 编写子程序
实验 12 编写 0 号中断的处理程序
实验 13 编写、应用中断例程
实验 14 访问 CMOS RAM
实验 15 安装新的 int9 中断例程
实验 16 编写包含多个功能子程序的中断例程
实验 17 编写包含多个功能子程序的中断例程
课程设计 2

Debug 工具

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

Debug 功能

A 命令:将指令直接汇编成机器码输入到内存中,用于小段程序的汇编及修改目标程序,所有输入的数字均采用十六进制,用户装入内存的汇编语句是连续存放的,若没有指定地址,并且前面没有使用汇编命令,该语句被汇编到 CS:0100 区域;

D 命令:查看内存中的内容,可以带参数也可省略参数,当省略参数时,命令 D 显示内容以 DS:0100 为起始,每次显示 128 个字节的内容。以后再执行不带参数的命令 D 时,Debug 将按上次的位置接着显示下去,带参数的方式有 d [起始位置]、d [起始位置] [结束位置]、d [起始位置] [L长度]

R 命令:查看、改变 CPU 寄存器的内容,当直接输入 r 时,Debug 将会显示出当前所有寄存器和标志位的状态,输入 r [寄存器] 可以改变 CPU 寄存器的内容;

E 命令:改写内存中的内容,使用方式为:e [起始位置],可修改当前字节的值,如果还要修改后续的内容,可以按空格键继续;

U 命令:将内存中的机器指令翻译成汇编指令,使用方法是:e [范围]

T 命令:单步执行,每次只执行一条代码语句,遇到子程序后进入子程序逐条执行代码,可以理解为 step into,默认从 CS:IP 处开始运行;

P 命令:类似 T 命令,不过遇到子程序调用的时候直接执行完子程序代码,不会进入子程序逐条执行,可以理解为 step over。另外,在遇到循环指令时,会直接执行到 CX=0

G 命令:该命令后面可以跟地址和断点,即格式为 g [=address] [breakpoints],运行到内存指定位置的代码后暂停,如果不加参数默认是从当前 IP 运行到程序结束。

标志寄存器在 Debug 中的表示


标志 值为 1 的标记 值为 0 的标记
of OV NV
sf NG PL
zf ZR NZ
pf PE PO
cf CY NC
df DN UP


CF:进位标志位
进行无符号数运算的时候,若存在运算结果的最高有效位向更高位的进位,或是从更高位借位,CF = 1,否则 CF = 0;
OF:溢出标志位
进行有符号数运算的时候,结果超过了机器所能表示的范围(溢出),则 OF = 1,否则 OF = 0;
DF:方向标志位
cld 指令将 DF 位置 0,si 与 di 递增,std 指令 将 DF 位置 1,si 与 di 递减;
SF:符号标志位
相关指令执行后,若结果为负,SF = 1,若为非负,SF = 0;
ZF:零标志位
相关指令执行后,若结果为 0,ZF = 1,若不为 0,ZF = 0;
PF:奇偶标志位
相关指令执行后,若其结果的所有 bit 位中 1 的个数是为偶数,PF = 1,若为奇数 PF = 0;

这里的相关指令指 add,sub,mul,div,inc,or,and 等,它们大都是运算指令(进行逻辑或算术运算),不包括 mov,push,pop 等传送指令。

8086 CPU 寄存器总结

基本介绍(引自百度)

Intel 8086 拥有四个 16 位的通用寄存器,也能够当作八个 8 位寄存器来存取,以及四个 16 位索引寄存器(包含了堆栈指标)。资料寄存器通常由指令隐含地使用,针对暂存值需要复杂的寄存器配置。它提供 64K 8 位元的输出输入(或 32K 16 位元),以及固定的向量中断。大部分的指令只能够存取一个内存位址,所以其中一个操作数必须是一个寄存器。运算结果会储存在操作数中的一个寄存器。

Intel 8086 有四个内存区段(segment)寄存器,可以从索引寄存器来设定。区段寄存器可以让 CPU 利用特殊的方式存取 1 MB 内存。8086 把段地址左移 4 位然后把它加上偏移地址。大部分的人都认为这是一个很不好的设计,因为这样的结果是会让各分段有重叠。尽管这样对组合语言而言大部分被接受(也甚至有用),可以完全地控制分段,使在编程中使用指针(如C编程语言) 变得困难。它导致指针的高效率表示变得困难,且有可能产生两个指向同一个地方的指针拥有不同的地址。更坏的是,这种方式产生要让内存扩充到大于 1 MB 的困难。而 8086 的寻址方式改变让内存扩充较有效率。

8086 处理器的时钟频率介于 4.77MHz(在原先的IBM PC频率)和 10 MHz之间。8086 没有包含浮点指令部分(FPU),但是可以通过外接数学辅助处理器来增强浮点计算能力。Intel 8087 是标准版本。

寄存器介绍

8086 拥有 4 个段寄存器,分别是:

  1. CS(code segment):16位的代码段寄存器;
  2. DS(data segment):16位的数据段寄存器;
  3. ES(extra segment):16位的扩展段寄存器;
  4. SS(stack segment):16位的堆栈段寄存器;

8086 通过 CS 与 16 位的指令指针寄存器 IP 一起来指示 CPU 当前要读取指令的地址(CS:IP),于是可以通过改变 CS、IP 中的内容来控制 CPU 执行目标指令。

8086 还拥有 8 个通用寄存器:即 AX、BX、CX、DX、BP、SP、SI、DI,其中:

  1. 4 个数据寄存器:AX、BX、CX、DX;
  2. 2 个地址指针寄存器:BP(base pointer)、SP(stack pointer);
  3. 2 个变址寄存器:SI(source index)、DI(destination index)。

4 个数据寄存器也能够当作 8 个 8 位寄存器来存取,即 AL、AH、BL、BH、CL、CH、DL、DH。

AX、DX 在使用 div 指令和 mul 指令时,总是 DX 为高 16 位,AX 为低 16 位,两者可以表示一个 32 位的双字型数据。

CX 默认为 loop 指令的循环计数器。

在以栈的方式访问内存空间时,通常将栈顶的段地址存放在段寄存器 SS 中,偏移地址存放在 SP 中,使得任意时刻,SS:SP 指向栈顶元素。

标志寄存器 FR(flags register),共 16 位,其中存储的信息通常被称为程序状态字(PSW),用来存储相关指令的某些执行结果、为 CPU 执行相关指令提供行为依据、控制 CPU 的相关工作方式。

寻址方式

8086 采用一种在内部用两个 16 位地址合成的方法来形成一个 20 位的物理地址,
即:物理地址=段地址×16+偏移地址

存放段地址的寄存器可以是默认的(DS),也可以显性给出。

给定内存单元偏移地址定位内存单元的方法被称为寻址方式。


指令系统总结


参考博文

以下也包括做实验时参考过的一些文章和视频

汇编语言答案 / HK_Mayfly

CSDN: OrangeHap / 汇编语言(第三版)实验

CSDN: shaco_的博客

CSDN: 洋葱汪 / 王爽《汇编语言》笔记(详细)

CSDN: 迂者-贺利坚 / no stack segment警告为何还在?

CSDN: 迂者-贺利坚 / 调整DOSBox的窗口大小:跨过三连坑

CSDN: shidan77 / DEBUG 中T、P、G命令的用法与区别

CSDN: _毛豆豆 / Debug命令详解

bilibili: 紫狐遗梦 / 汇编语言从0开始 重制版

百度百科: 8086