汇编语言程序设计

1. 课程说明

本课程基于《汇编语言(第 2 版)》郑晓薇 编著,机械工业出版社,可以配合该教材使用。本课程由郑晓薇授权制作,提取教材中的实例以及实验内容,可以在实验楼环境中完成所有实例及实验。实验课程制作符合教材原版实例驱动教学以及实验训练贯穿始终的特点。

本教材可在 当当网 购买(点击链接即可进入购买页面)。

本课程实验列表中的最后模块为配套教材的习题参考答案,可供读者学习参考。

2. 实验环境

DOS 环境:

实验环境中安装有 dosemu 可以模拟 DOS 环境,并提供 DEBUGMASMLINK 等汇编语言开发程序。

3. 实验程序的下载保存

在虚拟机的 dos 子目录中编写调试好的程序可以通过虚拟机的下载功能保存到本地机中。

(1)先在桌面上打开主文件夹,将 dos 文件夹中的汇编语言程序复制到 /home/shiyanlou/Code 文件夹中

enter image description here

(2)点击虚拟机上方的下载代码按钮,在弹出的对话框中按下载后,会自动将 Code 子目录压缩下载到本地机。

enter image description here

4. 汇编语言程序设计初步

前面两个实验我们介绍了 DEBUG 的用法、汇编指令的构成和寻址方式,在 DEBUG 下用几条简单的汇编指令实现了加减运算。我们知道,汇编语言与微型计算机系统密切相关。

本书以 80X86 系列微型计算机为基础,以 MASM 5.0 为汇编上机实验环境,重点介绍 Intel 8086 指令系统。Intel 8086 指令系统中有 100 多条指令,利用这些指令可以编写出复杂的程序实现更多功能。

汇编语言是直接控制计算机硬件工作的最简便的语言。学习了汇编语言可具有在 CPU 寄存器级上进行控制和操作的能力,可获得直接对计算机硬件底层编程的经验。学习汇编语言与学习高级语言的不同之处是要学习如何深入到计算机的内部进行控制,包括控制 CPU 的数据寄存器、地址寄存器、标志寄存器;对存储器的读写操作,对输入设备和输出设备的访问等等。

下面我们先从一个简单的例子入手学习汇编语言编程。

4.1 一个计算的例子

编写一个汇编语言程序,实现下列公式计算(假设 X = 4、Y = 5)。

汇编指令如下:

如果在 DEBUG 下用 A 命令输入这些指令,必须把 X、Y 换成具体的数值(假设 X = 4、Y = 5);Z、Z1 是存储单元地址,最后两条指令可写为 MOV [0],AL 和 MOV [1],AH,这样才能用 T 命令执行。

D:\dos〉DEBUG
-A
MOV AL,4 ; X = 4
ADD AL,5 ; Y = 5
MOV BL,8
IMUL BL
MOV BL,4
MOV B,0
SUB AX,BX
MOV BL,2
IDIV  BL
MOV [0],AL
MOV [1],AH

最后我们使用 T 命令执行。

采用 DEBUG 的 A 命令输入程序的做法明显不方便,一是无法给出变量名即符号地址,二是调试修改程序不便。因此,采用编写源程序的方式更有利于程序的调试和执行。

点击右下角的下一步,学习如何进行源程序的编写。

4.2 编写汇编语言源程序

一个完整的汇编语言源程序需要增加段定义伪指令和定义数据存储单元伪指令等必须有的伪指令。伪指令与 C 语言等高级语言中的说明性语句的含义类似,起到说明作用。有了伪指令,系统在汇编该程序时,就会正确的将源程序翻译、连接成可执行文件。(有关伪指令的其他用法参看本教材 4.2 节)

我们先给这个源程序起名为 ABC.ASM(汇编源程序的扩展名为.ASM)。在宿主机中用记事本 gedit 或者在 dos 子目录下用 edit 输入源程序。

实验步骤:

(1)双击实验楼环境桌面上的记事本 gedit,录入下列程序(分号后为注释,可不输入)

汇编语言源程序既可以用大写字母也可以用小写字母书写。

(2)按 save 按钮保存程序:

(3)选择路径、文件夹及输入文件名:

4.3 从源程序到可执行程序

汇编语言程序建立及汇编过程如图所示。

用户编写的源程序要经汇编程序 MASM 汇编(翻译)后生成二进制目标程序,文件名默认与源程序同名、扩展名为 .OBJ;再经过 LINK 连接生成可执行程序,文件名默认与源程序同名、扩展名为 .EXE。

**注意**:源程序一定要和 MASM、LINK 文件放在同一个文件夹中(在实验楼的环境中,它们都在 dosemu 环境的 D:\dos\ 文件夹中,可以进入这个目录后用 dir 命令查看)。

执行 MASM 和 LINK 命令时需要按多次回车。

执行步骤:

(1)输入汇编命令 masm abc.asm

**注意**:此处显示 0 个警告性错误,0 个严重性错误。如果有错误,必须对源程序进行修改。有关出错提示信息参见教材附录 B。

(2)输入连接命令 link abc.obj

**注意**:此处有一个警告性错误:no stack segment 没有堆栈段。这个提示是由于我们的程序中没有定义堆栈段,此错误可以忽略,不影响生成 .exe 文件。如果出现严重性错误,必须再检查一下源程序有无错误。

(3)用 dir 查看一下

已经生成了 abc.exe 可执行程序了。如果程序有错误,再回到记事本修改错误;之后需要重新汇编和连接。

(4)接着运行该程序 abc.exe(运行的方式是直接在 dosemu 中输入 abc.exe),可以看到没有显示任何结果就退回到 DOS 下了。

4.4 在 DEBUG 下执行程序

如果源程序无错误,就能汇编、连接成为可执行程序 abc.exe。

由于该程序没有写显示结果的指令语句,要想观察结果必须用 DEBUG 调试工具。

(1)输入 DEBUG abc.exe

(2)输入两次 U 命令后可以看到结束程序语句 MOV AH,4C 指令对应的偏移地址是 0023,这就是断点(所谓断点,就是程序执行到该处停下来不再继续)。用 G 0023(G 断点)执行程序。此时得到 AX=0022,再执行 D DS:0 查看存储单元,第 0 号单元是 04,即 X 单元,05 是 Y 的值,22 就是计算结果 Z 的十六进制数。

(3)按 Q 退出 DEBUG

5. 带彩色显示的算术程序

本节实验取自教材中第四章的《实例四 带彩色显示的算术程序》。

5.1 简化的程序结构

从 MASM 5.0 开始,提供了简化的段定义结构,这种结构用于小规模的程序设计中。一般格式为 .MODEL SMALL。这种格式是小型模式,程序可以有一个代码段、一个数据段,每段不大于 64 KB。

如果在实验楼的 Dosemu 中无法识别小模式的程序,可以将程序改为正常的段定义格式。

下面通过设计含有键盘输入和定位显示的十进制数运算程序,来复习 BCD 码的概念、算术运算指令、十进制调整指令、键盘输入、光标定位、中断调用、屏幕及显示缓冲区等内容,以加深对汇编语言程序设计的理解。

**注意**:MASM 及 LINK 程序放在 D 盘的 dos 目录下,可以在 dosemu 环境中输入 D: 切换到 D 盘,然后使用命令 cd dos 进入 D:\dos〉 目录。

5.2 屏幕显示和键盘输入

在汇编语言中,凡是涉及到键盘输入、屏幕显示等输入输出操作,都可以用软件中断指令 INT n 的功能调用来实现。所谓功能调用是计算机系统设计的简单 I / O 子程序,能方便地访问系统的硬件资源。

在微机系统中,功能调用分两个层次,最底层的是 BIOS 功能调用,其次是 DOS 功能调用,它们都是通过软件中断指令 INT n 来进行调用的。除了用 INT 指令实现输入和显示之外,还可以通过直接写显示缓冲区的方式显示字符。

(1)DOS 功能调用

DOS 的功能调用采用 INT 21H 指令,调用时要求在 AH 中提供功能号,在指定的寄存器和存储单元中提供调用必需的参数和缓冲区地址,执行后系统在 AL 中放入返回参数。

常用的 DOS 功能调用有 5 个:

  • 1 号 DOS 功能调用:键盘输入 1 个字符
  • 2 号 DOS 功能调用:显示器输出 1 个字符
  • 9 号 DOS 功能调用:显示字符串
  • 10 号 DOS 功能调用:键盘输入缓冲区
  • 4CH 号 DOS 功能调用:返回 DOS 控制

**注意**:I/O 处理操作的都是 ASCⅡ 码,对于键盘输入的数字,做计算时需将 ASCⅡ 码转变为二进制数,输出显示数据时需将二进制数转为 ASCⅡ 码。数字 0~9 的 ASCII 码为 30H~39H,可以看出两者之间相差 30H。

(2)DOS 功能调用例子

例子:显示两行字符串(回车换行功能)。第 1 行为“Input x:”,第 2 行为“Output y=x+1:”。从键盘输入 x,输出 y = x + 1 的值。

实验步骤:

(1)双击桌面上的记事本 gedit,录入下列程序,在 D 盘 dos 下保存为 test3-2.asm

data segment  
    mess1 db 'Input x:','$'
    mess2 db 0ah,0dh, 'Output y:$'   ;0ah和0dh是换行和回车 
    y db ?
data ends
code segment
assume cs:code,ds:data
start: mov ax, data
mov ds,ax        ;数据段的段地址→ds
mov dx,offset mess1
mov ah,9           ;显示提示信息“Input x:”
int 21h
mov ah,1    ;1号功能,键盘输入,键入的值在al
int 21h
add al,1        ;al+1→al 
mov y,al        ;保存到y单元 
mov dx,offset mess2        
mov ah,9    ;在下一行显示提示信息“Output y:”        
int 21h
mov ah,2    ;2号功能,显示一个字符
mov dl,y     ;显示的字符要放入dl,显示x+1的值
int 21h
mov ah,4ch
int 21h
code ends
end start

(2)双击 dosemu 图标,进入 dos 虚拟机。输入 DOS 命令,从 C 盘进入 D 盘,再进入 dos 子目录。

(3)经过汇编 masm test3-2.asm,连接 link test3-2.obj,生成 test3-2.exe。

(4)在 DOS 下执行 test3-2 程序。从键盘输入 x,显示出 y 的值

5.3 实验示例一

**关注点**:键盘输入,彩色字显示

例子:用简化的程序格式从键盘输入两个一位的十进制数,做加法运算。相加后以蓝底黄字显示在屏幕上。

设计思路

(1)键盘输入用 DOS 中断调用 1 号功能;显示采用写显存方法;

(2)经非压缩 BCD 码加法调整指令 AAA 调整后会将 AL 的高 4 位清零,因此键盘输入的数字不必去掉 30H,可直接运算;

(3)用 BIOS 中断调用 INT 10H 的 3 号功能获得光标的位置,让结果显示在光标处;

(4)由于计算结果不会超过两位十进制数,可用 SI 寄存器保存十进制数的 ASCII 码。

实验步骤

(1)双击桌面上的记事本 gedit,录入下列程序:

(2)在 dos 子目录下保存为 4-8.asm,经过汇编 masm 4-8.asm,连接 link 4-8.obj,生成了 4-8.exe。

D:\dos〉masm 4-8.asm
D:\dos〉link 4-8.obj
D:\dos〉dir
D:\dos〉4-8.exe

**注意**:如果实验楼环境下的 DOS 不识别简化的程序模式 .mode small,则需将程序修改为正常的段定义格式即可。

(3)运行结果:

程序运行时,当输入 5、6 之后,显示等号和加法结果。BCD 码调整指令请参看本教材的 4.3.7 节。DOS 中断调用 INT 21H 以及 BIOS 中断调用 INT 10H,除了本章用 3 号功能获得光标的位置之外的其它功能,在第 9 章将作详细介绍。

**小贴士**:彩色字符显示属性字节为前景色由 4 位(0~3 位)组合,背景色由 3 位(4~6 位)组合。最高位 BL 表示闪烁,RGB 为红、绿、蓝,I 代表亮度。例如蓝底黄字的属性值为 1EH。表 4-3 列出了 16 种颜色组合。

5.4 实验实例二

例子:从键盘输入两个一位的十进制数,做乘法运算。相乘的结果保存在存储单元 X 中,算式显示在屏幕上。用简化的程序格式。

设计思路

(1)用 DOS 中断调用的 1 号功能输入数据,用 2 号功能显示结果,9 号功能显示提示信息;

(2)做乘法时必须将输入数字的 ASCII 码去掉,转换成数值;

(3)乘法之后用十进制调整指令 AAM;

(4)将要显示的数值变为 ASCII 码。

实验步骤

(1)双击桌面上的记事本gedit,录入下列程序:

(2)在 dos 子目录下保存为 4-9.asm,经过汇编 masm 4-9.asm,连接 link 4-9.obj,生成 4-9.exe。

D:\dos〉masm 4-9.asm
D:\dos〉link 4-9.obj
D:\dos〉dir
D:\dos〉4-9.exe

(3)运行结果:

实验结果分析如下:

DOS 中断调用的 1 号、2 号、9 号功能提供了对键盘和显示器的操作和控制,为用户提供了方便的调用指令(见本书 4.4 节)。本程序的输入和显示在同一行上,没有换行。

5.5 实验任务

实验目的

通过设计顺序程序,掌握汇编语言程序设计思路和编写方法,并通过实验观察和分析程序的执行结果。熟练掌握数值计算程序设计方法。

实验内容

参考 5.4 小节中给出的示例二,完成下列实验内容:

  1. 设计程序。实现 Y = 2X + 3,X 是一位十进制数。要求 X 从键盘输入,在下一行上显示’Y=2X+3=’ 以及十进制计算结果。参考结果:Alt text
  2. 设计程序。分别从键盘输入一位十进制数 X 和 Y,用乘除指令实现 Z = (X + 20) /6 - 4Y,显示出计算结果。

实验要求

  1. 写出设计思路和程序源码;
  2. 实验内容用截图形式记录实验结果;
  3. 写出实验结果分析。

实验拓展

  1. 如果以黄底红字显示结果,程序应该怎么改?
  2. 自由设计一个计算型实验题目并编程实现。

类似文章