汇编语言程序设计实验篇(emu8086)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.汇编语言程序设计实验篇
1.1.汇编系统软件简介
Emu8086-Microprocessor Emulator是集源代码编辑器、汇编/反汇编工具以及debug 的模拟器。
它能模拟一台"虚拟"的电脑运行程序,拥有独立的“硬件”,避免访问真实硬件。
该软件兼容Intel的下一代处理器,包括PentiumII、Pentium4。
利用该软件提供的调试工具,能够单步跟踪程序,观察程序执行过程中寄存器、标志位、堆栈和内存单元的内容。
1.1.1创建程序
TEMPLATE程序
本章与指令相关的实验都是用COM TEMPLATE类型的程序完成的。
打开emu8086,在“welcome…”对话框中,单击按钮,创建文件。
在“choose code template”对话框中,选择“COM template-simple and tiny executable file format, pure machine code.”后,单击按钮。
在如所示的编辑界面中,在“;add your code here”部分输入相应的指令,第一条指令默认的偏移地址为100h。
输入全部指令后,单击按钮,保存相应的程序段。
2.EXE TEMPLATE程序
本章与DOS功能调用和汇编源程序相关的实验都是用EXE TEMPLATE程序完成的。
打开emu8086,在“welcome…”对话框中,单击按钮,创建文件。
在“choose code template”对话框中,选择“EXE template-advanced executable file.header: relocation, checksum.”后,单击按钮。
在如图所示的编辑界面中,已经可以给出了源程序的框架,包含数据段、堆栈段和代码段的定义以及必要的功能调用等,在“add your data here”和“;add your code here”部分可以分别输入相应的变量定义和指令。
输入全部指令后,单击按钮,保存相应的程序。
1.1.2执行程序
在编辑界面中,如图所示,单击按钮,自动完成源程序的编译和链接。
在
“emulator”对话框中(),左边部分列出了寄存器的当前值,右边部分是已经输入的程序段,中间部分是右边每条指令的物理地址和对应的机器代码,中间的文本框中列出了当前指
令的CS和IP。
单击按钮,可以单步执行一条指令;单击按钮,可以一次执行完所有程序;单击按钮,可以重新回到第一条指令的位置处;单击按钮,可以重新加载另一个程序。
修改“emulator”对话框中文本框的内容,也可以观察其它段的内容,在图所示界面中,DS=0700H,若要察看该数据段中偏移地址为6000H位置处的内存单元内容,可以在文本框中输入0700:6000,显示结果如图所示,中间部分依次列出从该地址开始的所有字节的内容。
在“emulator”对话框的底部,单击按钮,可以观察栈的内容;单击按
钮,可以观察标志寄存器中标志位的内容。
在“emulator”对话框中,选择“view”菜单中的“memory”菜单项,也可以观察内存的情况。
在“Random Access Memory”对话框中,可以修改文本框中的值可以确定所要观察的地址,该值由段基地址:段内偏移地址构成,如图所示,当前要观察的内存地址为(6000:0010)。
在显示结果中,左边是逻辑地址,中间是从该地址的开始连续16个字节的内容,右边是每个字节对应的字符。
在该对话框中,也可以直接修改存储器单元的值,如图所示,从60010H开始的连续4个字节的内容已经被修改为12H,34H,56H和78H。
1.2基础实验
1.2.1数据传送指令
1.实验目的
1)熟悉8086指令系统的数据传送指令及8086的寻址方式。
2)利用emu8086调试工具调试汇编程序。
2.实验设备
微型计算机、emu8086
3.实验原理
通用数据传送指令包括:1)通用数据传送指令,如MOV,PUSH,POP,XCHG,CBW,CWD;2)目标地址传送指令,如LDS,LES;3)标志传送指令,如LAHF,SAHF,PUSHF,POPF;4)输入输出指令,如IN,OUT,LEA
寻址方式包括:1)立即寻址;2)直接寻址;3)寄存器寻址;4)寄存器间接寻值;5)寄存器相对寻址;6)基址-变址寻址;7)基址—变址—相对寻址;8)隐含寻址
4.实验内容
(1)创建COM TEMPLATE程序,输入以下程序段,观察程序的执行情况,程序段如下:MOV BL,08H;BX=?
MOV CL,BL;CL=?
MOV AX,03FFH;AX=?
MOV BX,AX;BX=?
MOV DS:[6000H],BX;DS:[6000H]=?(提示:在emulator对话框中间的文本框中输入段基地址:段内偏移地址,可以观察其它逻辑段相应存储单元的内容)
(2)创建COM TEMPLATE程序,用以下程序段将一组数据压入PUSH堆栈区,然后通过
三种不同方式出栈。
观察栈的变化情况(提示:在emulator对话框中,单击按钮可以察看栈中内容)以及出栈后数据的变化情况,并把结果填入表1-1中。
程序段如下:MOV AX,0102H
MOV BX,0304H
MOV CX,0506H
MOV DX,0708H
PUSH AX
PUSH BX
PUSH CX
PUSH DX
第—种出栈方式的指令序列:
POP DX
POP CX
POP BX
POP AX
第二种出栈方式的指令序列(注:替换掉第—种出栈方式的指令序列):
POP AX
POP BX
POP CX
POP DX
第三种出栈方式的指令序列(注:替换掉第二种出栈方式的指令序列):
POP CX
POP DX
POP AX
POP BX
表1-1数据传送实验结果表格
(3
值(提示:在“emulator”对话框中,可以直接修改寄存器的值;选择“view”菜单中的“memory”菜单项可以设置内存单元的值),其中BX=0010H,SI=0001H,[60010H]=12H,[60011H]=34H,[60012H]=56H,[60013H]=78H,[60120H]=0ABH,[60121H]=0CDH,[60122H]=0EFH,观察指令执行后AX中的内容。
1)MOV AX,1200H
2)MOV AX,BX
3)MOV AX,[0120H]
4)MOV AX,[BX]
5)MOV AX,0110H[BX]
6)MOV AX,[BX][SI]
7)MOV AX,0110H[BX][SI]
(4)创建COM TEMPLATE程序,试分别用8086的直接寻址、寄存器间接寻址、变址寻址、寄存器相对寻址传送指令编写程序段,将DS:6000H字节存储单元中的内容传送到DS:6020H单元中。
(5)设AX=1111H,BX=2222H,[DS:6010H]=3333H。
试编写COM TEMPLATE程序,将AX的内容与BX的内容交换,然后再将BX的内容与DS:6010H单元的内容进行交换。
(6)若[DS:6000H]=0EEFFH,[ES:7000H]=0CCDDH,请编写COM TEMPLATE程序,将两个存储单元的内容交换。
5.实验习题
指出下列指令的错误并加以改正,并在emu8086中验证。
1)MOV [BX],[SI]
2)MOV AH,BX
3)MOV AX,[SI][DI]
4)MOV BYTE PTR[BX],2000H
5)MOV CS,AX
6)MOV DS,2000H
6.实验报告要求
1)整理源程序段和运行结果。
2)给出几种在emu8086中察看内存单元的方法。
1.2.2算术逻辑运算指令
1.实验目的
1)熟悉算术逻辑运算指令的功能。
2)了解标志寄存器中各标志位的意义以及指令执行对它的影响。
2.实验设备
微型计算机、emu8086
3.实验原理
算术运算指令包括:1)加法指令,如ADD,ADC,INC;2)减法指令,如SUB,SBB,DEC,NEG,CMP;3)乘法指令,如MUL,IMUL;4)除法指令,如DIV,IDIV。
逻辑运算指令包括:AND,OR,NOT,XOR,TEST
4.实验内容
(1)创建COM TEMPLATE程序,输入以下程序段,单步执行并记录标志位的变化情况(提示:在emulator对话框中,单击按钮察看标志寄存器的值)。
程序段及结果表格如
表1-2。
表1-2算术逻辑运算实验结果表格
(2)用BX作为地址指针,从BX所指的内存单元[0010H]开始连续存入三个无符号数(10H、04H、30H),计算内存单元中这三个数的和,并将和放在0013H单元中,再求出这三个数的乘积,并将乘积存入0014单元中,写出完成此功能的COM TEMPLATE程序。
(3)创建COM TEMPLATE程序,写出完成下述功能的程序段,并指出程序运行后AX=? 1)将15H传送到AL;
2)再将AL的内容乘以2;
3)将15H传送到BL;
4)把AL的内容乘以BL的内容。
(4)创建以下两个程序段的COM TEMPLATE程序并上机验证。
1)给数据段中从偏移地址1000H开始的12个字存储单元的内容赋值,请将第4条比较指令填写完整(划线处)。
MOV SI,1000H
NEXT: MOV WORD PTR[SI],1
ADD SI,2
CMP SI,
JNE NEXT
2)假定要按高地址到低地址的顺序进行清除操作(高地址从1016H开始),则上述程序段应如何修改?
5.实验习题
简要说明ADD、SUB、AND、OR指令对标志位的影响。
6.报告要求
1)整理源程序段和运行结果,回答实验中的问题。
1.2.3移位指令
1.实验目的
1)熟悉移位指令的功能。
2)了解标志寄存器中各标志位的意义以及指令执行对它的影响。
2.实验设备
微型计算机、emu8086
3.实验原理
移位指令包括:1)非循环移位指令,如SAL,SAR,SHL,SHR;2)循环移位指令,如ROL,ROR,RCL,RCR
4.实验内容
(1)创建COM TEMPLATE程序,输入以下程序段,单步执行并记录标志位的变化情况(提
示:在emulator对话框中,单击按钮可以察看标志寄存器的值)。
程序段及结果表格如表1-3。
表1-3移位实验结果表格1
(2)写出完成下述功能的COM TEMPLATE程序并上机验证,程序运行后的商=?
1)传送数据2058H到[DS:1000H]单元中,数据12H到DS:1002H单元中;
2)把DS:1000H单元中的数据传送到AX寄存器;
3)把AX寄存器的内容算术右移二位;
4)再把AX寄存器的内容除以DS:1002H字节单元中的数;
5)最后把商存入字节单元DS:1003H中。
(3)创建COM TEMPLATE程序,输入以下程序段,单步执行并记录每一条指令对内存单元的影响结果(提示:在“emulator”对话框中,选择“view”菜单中的“memory”菜单项可以察看内存单元的值),分析结果并说明该程序段的功能是什么。
程序段及结果表格如表1-4。
表1-4移位实验结果表格2
5.实验习题
简要说明一般移位指令与循环移位指令之间的主要区别。
6.实验报告要求
整理源程序段和运行结果,回答实验中的问题。
1.2.4串操作指令
1.实验目的
1)熟悉串操作指令的功能。
2)了解串操作指令的使用方法。
2.实验设备
微型计算机、emu8086
3.实验原理
串操作指令包括:1)串传送指令MOVS;2)串比较指令CMPS;3)串扫描指令SCAS;4)串装入指令LODS;5)串存储指令STOS。
4.实验内容
(1)创建COM TEMPLATE程序,输入以下程序段,单步执行并根据结果回答后面的问题。
CLD
MOV DI,1000H
MOV AX,55AAH
MOV CX,10H
REP STOSW
上述程序段执行后:
1)从ES:1000H开始的16个字单元的内容是什么?(提示:在“emulator”对话框中,选择“view”菜单中的“memory”菜单项可以察看内存单元的值)
2)DI=?CX=?解释其原因。
(2)在上题的基础上,再输入以下程序段并执行,回答后面的问题。
MOV SI,1000H
MOV DI,2000H
MOV CX,20H
REP MOVSB
程序段执行后:
1)从ES:2000H开始的16个字单元的内容是什么?
2)SI=?DI=?CX=?并分析之。
(3)在以上两题的基础上,再分别输入以下三个程序段并运行之。
程序段1:
MOV SI,1000H
MOV DI,2000H
MOV CX,10H
REPZ CMPSW
程序段1执行后:
1)ZF=?根据ZF的状态,两个串是否比较完了?(提示:在emulator对话框中,单击
按钮可以察看标志寄存器的内容)
2)SI=?DI=?CX=?并分析之。
程序段2:
MOV [2008H],4455H
MOV SI,1000H
MOV DI,2000H
MOV CX,10H
REPZ CMPSW
程序段2执行后:
1)ZF=?根据ZF的状态,两个串是否比较完了?
2)SI=?DI=?CX=?并分析之。
程序段3:
MOV AX,4455H
MOV DI,2000H
MOV CX,10H
REPNZ SCASW
程序段3执行后:
1)ZF=?根据ZF的状态,在串中是否找到了数据4455H?
2)SI=?DI=?CX=?并分析之。
(4)从DS:6000H开始存放有一个字符串"This is a string",把这个字符串从后往前传送到DS:6100H开始的内存区域中(即传送结束后,从DS:6100H开始的内存单元的内容为"gnirts a si sihT"),试编写COM TEMPLATE程序并上机验证。
(提示:可以在数据区中直接输入字符串)
5.实验习题
1)简要说明执行串操作指令之前应初始化哪些寄存器和标志位。
2)总结串操作指令的用途及使用方法。
6.实验报告要求
整理源程序段和运行结果,对结果进行分析。
1.2.5DOS功能调用
1.实验目的
1)掌握简单的DOS系统功能调用。
2.实验设备
微型计算机、emu8086
3.实验原理
本节要用到的DOS功能命令包括:
从键盘输入单个字符的语句如下:
MOV AH,1
INT 21H
以上两条指令执行后,(AL)=从键盘输入的字符
在屏幕上显示单个字符的语句如下:
MOV DL,<要显示的字符>
MOV AH,2
INT 21H
注意:源程序中所有语法符号都必须是半角符号,而且不允许汉字字符。
在屏幕上显示字符串的语句如下:
LEA DX,<字符串变量名,字符串必须以字符′$′作为结束>
MOV AH,9
INT 21H
从键盘上输入字符串的语句如下:
LEA DX,<键盘缓冲区名>
MOV AH,0AH
INT 21H
4.实验内容
(1)字符的输入和输出
从键盘读入一个小写字母,输出字母表中倒数与该字母序号相同的那个字母。
例如输入首字母a,则输出最后一个字母z,输入第4个字母d则输出倒数第4个字母w。
程序流程图如图1-1所示。
开始
从键盘输入字符
′z′– AL + ′a′→AL
显示AL中的内容
返回DOS
图1-1字符输入输出的程序流程图
程序框架如下:
data segment
pkey db "press any key...$"
ends
stack segment
dw 128 dup(0)
ends
code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
从键盘输入一个字符的指令序列
根据流程图中转换算法编制的指令序列
用于显示结果的指令序列
lea dx, pkey
mov ah, 9
int 21h ; output string at ds:dx
; wait for any key....
mov ah, 1
int 21h
mov ax, 4c00h ; exit to operating system.
int 21h
ends
end start ; set entry point and stop the assembler.
编写EXE TEMPLATE程序(提示:计算’z’-al+’a’时,需要用sub指令),观察执行结果。
(2)字符串的输入和输出
从键盘输入一个字符串(以下说明中,假定键盘缓冲区的名字为KBUF,要显示的字符串变量名为STR),将输入的字符串传送给STR变量,在屏幕上显示STR变量中的内容。
程序流程图如图1-2所示。
开始
从键盘输入字符串到KBUF
将KBUF中的字符串传送到变量STR中:
1.字符串长度传送到CX
2.KBUF+2的偏移地址→SI,STR的偏移地址→DI
3.循环传送字符串中的每个字符(循环次数在CX中)
显示INFO中的内容
返回DOS
图1-2字符串输入输出的程序流程图
程序框架如下:
data segment
KBUF db 20, 0, 20 dup(20h)
STR db 20 dup(20h), ′$′
pkey db "press any key...$"
ends
stack segment
dw 128 dup(0)
ends
code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
从键盘输入字符串的指令序列
将KBUF传送到STR的指令序列
显示STR内容的指令序列
lea dx, pkey
mov ah, 9h
int 21h ; output string at ds:dx
; wait for any key....
mov ah, 1
int 21h
mov ax, 4c00h ; exit to operating system.
int 21h
ends
end start ; set entry point and stop the assembler.
编写EXE TEMPLATE程序(提示:CX的初始值不为0),观察执行结果。
5.实验习题
1)对实验内容1,在程序中增加显示提示字符串"Please input a lowercase letter"和" The inverse letter is:",修改程序并上机验证。
2)对实验内容2,在程序中增加显示提示字符串"Please input a string"和"The string you input is:",修改程序并上机验证。
6.实验报告要求
1)整理源程序段和运行结果。
2)说明DOS系统功能调用的10号功能对键盘缓冲区格式上有何要求。
3)DOS系统功能调用中的1、2、9、10号功能的输入输出参数有哪些?分别放在什么寄存器中?
4)总结汇编语言程序中如何实现字符和字符串的输入输出。
1.2.6顺序程序
1.实验目的
1)了解8086汇编程序的基本结构;
2)掌握顺序程序的基本设计方法。
2.实验设备
微型计算机、emu8086
3.实验原理
顺序程序是控制流仅有一个走向的程序,它主要用于解决一些无需进行判断分支,也无需循环执行的简单问题。
本节的实验内容与乘法和除法运算有关。
无符号数乘法运算使用MUL指令,有符号数乘法运算使用IMUL指令。
乘法运算属于隐含操作数的运算,因此在使用乘法指令前,需要先将乘数放入AL(8位乘法)或AX(16位乘法)中。
乘法指令执行后,乘积在AX(8位乘法)或DX:AX(16位乘法)中。
无符号数除法运算使用DIV指令,有符号数除法运算使用IDIV 指令。
除法运算属于隐含操作数的运算,因此在使用除法指令前,需要先将被除数放入AX (8位除法)或DX:AX(16位除法)中。
当除数为8位时,被除数应为16位;除数为16位时,被除数应为32位。
对无符号数除法,当被除数字长不够时,高位部分可直接补0;而对有符号数除法,当被除数字长不够时,必须使用符号扩展指令进行扩展。
除法运算执行后,结果在AX(8位除法)或DX:AX(16位除法),其中AL(8位除法)或AX(16位除法)中是商,AH(8位除法)或DX(16位除法)中是余数。
4.实验内容
在NUM变量中定义了5个符号数(字节类型),分别是U= 09H,V=16H,W=04H,X=17H,Y=05H,计算(U+V -W*X)/Y,将结果显示在屏幕上。
程序流程图如图1-3。
开始
[NUM]=U,[NUM+1]=V,
[NUM+2]=W,[NUM+3]=X,[NUM+4]=Y
第一步:计算W*X
1. [NUM+2]→AL(数据W送AL)
2. AL*[NUM+3]→AL(W*X乘积送AL)
3.AL→BL(乘积备份到BL)
第二步:计算U+V-W*X
1. [NUM]→AL(数据U送AL)
2. AL+[NUM+1]→AL(U+V之和送到AL)
3. AL-BL→AL(U+V-W*X,结果送到AL)
第三步:计算(U+V-W*X)/Y
1. AL符号扩展到AX
2. AX / [NUM+4]→AX ((U+V-W*X)/Y,商在AL中)
第四步:显示结果的高4位
1. AL中的结果暂存到BL
2. AL逻辑右移4位(取高4位)
3. AL的内容转换成ASCII码
4. 显示
第五步:显示结果的低4位
1. BL中暂存的结果送到AL
2. 保留AL中低4位,高4位清0
3. AL的内容转换成ASCII码
4. 显示
返回DOS
图1-3顺序程序的程序流程图
程序框架如下:
data segment
NUM db 09,16h,04h,17h,05h ;定义U,V,W,X,Y
pkey db "press any key...$"
ends
code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
lea si,NUM
;计算W*X,结果保存到al中
mov bl, al
;计算U+V,结果保存到al中
;计算U+V-W*X,结果保存到al中
cwb
;计算(U+V-W*X)/Y
mov bl,al
;显示结果的高4位
;显示结果的低4位
lea dx, pkey
mov ah, 9
int 21h ; output string at ds:dx
; wait for any key....
mov ah, 1
int 21h
mov ax, 4c00h ; exit to operating system.
int 21h
ends
end start ; set entry point and stop the assembler.
编写EXE TEMPLATE程序,观察执行结果。
5.实验习题
将数据改为U=0ABH,V=0EFH,W=12H,X=10H,Y=05H,上机验证结果是否正确?问题出在何处,应如何解决?
6.实验报告要求
1)写出完整的程序。
2)使用不同数据测试程序并解释运行结果。
1.2.7分支程序
1.实验目的
1)了解8086汇编程序的基本结构;
2)掌握分支程序的基本设计方法。
2.实验设备
微型计算机、emu8086
3.实验原理
分支程序是根据不同条件执行不同处理过程的程序。
分支程序的结构有两种:—种是二路分支,—种是多路分支。
它们的共同特点是在满足某一条件时,将执行多个分支中的某—分支。
本节的实验内容与数值和ASCII码间的转换有关,由于字符′0′~′9′的ASCII码是30H~39H,因此将数值0~9转换成对应的ASCII码时,需要在其基础上加30H;由于字符′A′~′F′的ASCII码是41H~46H,因此将数值A~F转换成对应的ASCII码时,需要在其基础上加37H。
另外,二进制数与十六进制数之间的关系是:每4位二进制数等于1位十六进制数。
在屏幕上显示单个字符的语句如下:
MOV DL,<要显示的字符>
MOV AH,2
INT 21H
4.实验内容
从键盘输入一个十进制正整数N(10≥N≥99),将其转换成十六进制数,转换的结果显示在屏幕上。
提示:键盘输入的内容都是ASCII码形式。
程序流程图如
图1-4。
图1-4程序流程图
程序框架如下:
data segment
STR db 3,0,3 dup(0)
MES db 'Input a decimal number(10~99):$'
MES1 db 0ah,0dh,’Show decimal number as hex:$'
pkey db "press any key...$"
ends
code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
;显示字符串Input a decimal number(10~99):
;从键盘输入一个两位的十进制数
;将表示十位数的字符转换成数值,保存到ah中
;将表示个位数的字符转换成数值,保存到al中
mov bl, al
;将ah和al表示的两位十进制数转换成十六进制数,保存到al中
mov bl, al
;显示字符串Show decimal number as hex:
;显示结果的高4位
;显示结果的低4位
lea dx, pkey
mov ah, 9
int 21h ; output string at ds:dx
; wait for any key....
mov ah, 1
int 21h
mov ax, 4c00h ; exit to operating system.
int 21h
ends
end start ; set entry point and stop the assembler.
编写EXE TEMPLATE程序,观察执行结果。
5.实验习题
1)如果输入的数在0~99范围内,如何修改程序才能使结果正确。
2)如果可以输入负整数,如何修改程序才能使结果正确。
6.实验报告要求
1)写出完整的程序。
2)使用不同数据测试程序并解释运行结果。
1.2.8循环程序
1.实验目的
1)了解8086汇编程序的基本结构
2)掌握循环程序的基本设计方法。
2.实验设备
微型计算机、emu8086
3.实验原理
循环程序是把一个程序段重复执行多次的程序结构。
循环程序包括三个部分:初始化部分、循环体、循环控制部分。
初始化部分用于对循环程序的参数(循环次数、控制条件、指针等)设置初值。
循环体是要被重复执行的程序段。
循环控制部分用于决定是否退出循环。
循环控制指令可以是转移指令或LOOP指令。
当已知循环次数或控制条件为ZF时,用LOOP 指令控制循环是最简单的方法。
本节实验显示的图形可以分为上下两部分。
对于上半部分图形,需要设置两层循环,其中外循环控制显示几行(初始为9,每次减1,减到0时结束);内循环控制当前行显示几个′*′(初值为1,每次加1)。
对于下半部分图形,也需要设置两层循环,其中外循环控制显示几行(初始为9,每次减1,减到0时结束);内循环控制当前行显示几个空格(初值为8,每次减1)和几个′*′(初值为1,每次加1)。
在屏幕上显示单个字符的语句如下:
MOV DL,<要显示的字符>
MOV AH,2
INT 21H
4.实验内容
在屏幕上显示如下图形。
*
**
***
****
*****
******
*******
********
*********
*
**
***
****
*****
******
*******
********
*********
程序的流程图如图1-5所示。
图1-5程序流程图程序的框架如下:
data segment
pkey db "press any key...$"
ends
code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
;初始化bl和bh,显示上半部分
next:
;内循环计数器 cl=bh
next1:
;显示’*’
cl=cl-1
;如果cl≠0,则转到next1
;显示’0DH’
;显示’0AH’
bh=bh+1
bl=bl-1
;如果bl≠0,则转到next
;初始化bl、ch和bh,显示下半部分
next2:
cl=ch;设置空格数
;如果cl=0,则转到next3
next4:
;显示’’
;cl=cl-1
;如果cl≠0,则转到next4
next3:
cl=bh
;如果cl=0,则转到next5
next6:
;显示’*’
cl=cl-1
;如果cl≠0,则转到next6
next5:
;显示’0DH’
;显示’0AH’
ch=ch-1
bh=bh+1
bl=bl-1
;如果bl≠0,则转到next2
lea dx, pkey
mov ah, 9
int 21h ; output string at ds:dx
; wait for any key....
mov ah, 1
int 21h
mov ax, 4c00h ; exit to operating system.
int 21h
ends
end start ; set entry point and stop the assembler. 5.实验习题
若要显示如下形式的三角形,该如何修改程序?
*
***
*****
*******
*********
***********
*************
***************
*****************
6.实验报告要求
1)写出完整的程序。
2)使用不同数据测试程序并解释运行结果。
1.3扩展实验
1.3.1统计排序
1.实验目的
1)掌握三种基本程序结构的设计方法。
2.实验设备
微型计算机、emu8086
3.实验原理
在屏幕上显示字符串的语句如下:
LEA DX,<字符串变量名,字符串必须以字符′$′作为结束> MOV AH,9
INT 21H
从键盘上输入字符串的语句如下:
LEA DX,<键盘缓冲区名>
MOV AH,0AH
INT 21H
在显示提示信息后和输入数据后,都需要回车换行,在这里我们用一个宏指令CRLF来实现。
注意,宏指令CRLF中又调用了另外一个带参数的宏指令CALLDOS。
宏指令一般定义在程序的最前面。
宏定义:
CALLDOS MACRO FUNCTION ;定义宏指令CALLDOS
MOV AH, FUNCTION
INT 21H
ENDM ;宏定义结束
CRLF MACRO FUNCTION ;定义宏指令CRLF
MOV DL,0DH ;回车
CALLDOS 2 ;2号功能调用用于显示DL中的字符
MOV DL,0AH ;换行
CALLDOS 2
ENDM ;宏定义结束
CRLF宏指令用2号DOS功能调用(显示一个字符)显示回车符与换行符的方法来实现回车换行。
2号DOS功能在显示回车符与换行符时实际上只是把光标移到下一行的开始,而并非把0DH和0AH显示在屏幕上。
在程序中凡是需要进行回车换行的地方只要把CRLF看成是一条无操作数指令直接使用即可。
在程序中若要使用CALLDOS宏指令,需要在CALLDOS宏指令后带上一个实参,该实参为DOS功能调用的功能号。
为了便于排序和统计,从键盘输入的数据先转换成二进制数存储,在最后显示结果前再把数据转换成ASCII码。
由于字符′0′~′9′的ASCII码是30H~39H,因此将数值0~9转换成对应的ASCII码时,需要在其基础上加30H;由于字符′A′~′F′的ASCII码是41H~46H,因此将数值A~F转换成对应的ASCII码时,需要在其基础上加37H。
可以采用冒泡排序法对数据排序。
在双重循环中,外层循环用于确定待比较的数据,内层循环在待比较的数据中确定一个最小数并将该数放到合适的位置。
比较数据时,可以先从最后一个数开始,通过与前一个数的比较,将小数放在前面,大数放在后面,即如果后面的数小于前面的数,需要交换两个数的位置。
4.实验内容
在屏幕上显示提示信息“Please input 10 numbers:”,提示用户输入10个数(数的范围在0~99之间),然后从键盘上读入这10个数。
接着对这10个数从小到大进行排序,并统计0~59、60~79、80~99的数各有多少。
最后在屏幕上显示排序后的数(每个数之间用逗号分隔)并显示统计的结果。
显示格式如下:
Sorted numbers: xx,xx,xx,xx,xx,xx,xx,xx,xx,xx
0-59: xx
60-79: xx
80-99: xx
程序流程图如图1-6所示。
开始
显示提示信息
循环从键盘读入10个数据
对数据进行排序
对数据进行统计
显示排序后的数据和统计结果
返回DOS
结束
图1-6程序流程图
程序的框架如下:
;定义宏CALLDOS
;定义宏CRLF
data segment
;定义提示信息MESSAGE,显示'Please input 10 numbers:'
MESSAGE db 'Please input 10 numbers:',0dh,0ah,'$'
;定义键盘缓冲区KB_BUF,包括可接收最大字符数为3,实际输入字符数,输入的字符
KB_BUF db 3
ACTLEN db 0
BUFFER db 3 DUP(0)
;定义数据NUMBERS,存放转化后的二进制数据
NUMBERS db 10 DUP(0)
;定义统计结果LE59,GE60,GE80,分别存放小于60,60~80之间和大于80三个区间的统计结果
LE59 db 0
GE60 db 0
GE80 db 0
;定义显示结果信息SORTSTR,显示'Sorted number:'
SORTSTR db 'Sorted number:'
;定义显示排序后的结果SORTNUM,包括字符和分割符,回车和换行
SORTNUM db 10 DUP(20h,20h,','),0dh,0ah
;定义显示信息MESS00,包括'0-59:'和统计结果,回车和换行
MESS00 db '0-59:',30h,30h,0dh,0ah
;定义显示信息MESS60,包括'60-79:'和统计结果,回车和换行
MESS60 db '60-79:',30h,30h,0dh,0ah
;定义显示信息MESS80,包括'80-99:'和统计结果,回车和结束符
MESS80 db '80-99:',30h,30h,0dh,0ah,'$'
pkey db "press any key...$"
ends
code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
;显示MESSAGE
mov cx, 10
lea di, NUMBERS
LP1:
;从键盘读入一个数据,转换成二进制数存入DI所指向的内存单元
;将输入的字符转换成数值,保存在al中
mov di, al
inc di
CRLF 2 ;在下一行输入
loop LP1 ;直到10个数据都输入完
lea di, NUMBERS
mov bl, 10
;对NUMBERS中的10个数据排序
lea si, NUMBERS
mov cx,10
;统计NUMBERS中的10个数据,结果放在GE80、GE60和LE59中
lea si, NUMBERS
lea di, SORTNUM
mov dx, 10
;排序后的10个数据转换成ASCII码依次存入SORTNUM中
;把GE80、GE60和LE59中的统计结果转换成ASCII码存入MESS80、MESS60和MESS00字符串中
; 显示统计结果
lea dx, SORTSTR
mov ah, 9
int 21h
lea dx, pkey
mov ah, 9
int 21h ; output string at ds:dx
; wait for any key....
mov ah, 1
int 21h
mov ax, 4c00h ; exit to operating system.
int 21h
ends
end start ; set entry point and stop the assembler.
5.实验习题
1)从键盘输入任意一个字符串,统计其中A~Z字符出现的次数(不分大小写,没出现次数就记为0),并把结果显示在屏幕上。
显示格式如下:
A: xx
B: xx
…
Z: xx
3)从键盘分别输入两个字符串,若第二个字符串包含在第一个字符串中就显示‘MATCH’,否则显示‘NO MATCH’。
6.实验报告要求
1)写出完整的程序。
1.3.2密码验证
1.实验目的
1)掌握三种基本程序结构的设计方法。
2.实验设备
微型计算机、emu8086
3.实验原理
在屏幕上显示字符串的语句如下:
LEA DX,<字符串变量名,字符串必须以字符′$′作为结束>
MOV AH,9
INT 21H
在屏幕上不回显字符的语句如下:
MOV AH,8
INT 21H
以上两条指令执行后,(AL)=从键盘输入的字符
在屏幕上显示单个字符的语句如下:
MOV DL,<要显示的字符>。