1、1. 汇编语言程序设计实验篇 1.1. 汇编系统软件简介 Emu8086-Microprocessor Emulator是集源代码编辑器、汇编/反汇编工具以及debug的模拟器。它能模拟一台"虚拟"的电脑运行程序,拥有独立的“硬件”, 避免访问真实硬件。该软件兼容Intel的下一代处理器,包括PentiumII、Pentium4。利用该软件提供的调试工具,能够单步跟踪程序,观察程序执行过程中寄存器、标志位、堆栈和内存单元的内容。 1.1.1 创建程序 1. COM TEMPLATE程序 本章与指令相关的实验都是用COM TEMPLATE类型的程序完成的。打开emu8086,在“wel
2、come…”对话框中,单击按钮,创建文件。 在“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,在
3、welcome…”对话框中,单击按钮,创建文件。 在“choose code template”对话框中,选择“EXE template-advanced executable file.header: relocation, checksum.”后,单击按钮。 在如图所示的编辑界面中,已经可以给出了源程序的框架,包含数据段、堆栈段和代码段的定义以及必要的功能调用等,在“add your data here”和“;add your code here”部分可以分别输入相应的变量定义和指令。 输入全部指令后,单击按钮,保存相应的程序。 1.1.2 执行程序 在编辑界面中,
4、如图所示,单击按钮,自动完成源程序的编译和链接。在“emulator”对话框中(),左边部分列出了寄存器的当前值,右边部分是已经输入的程序段,中间部分是右边每条指令的物理地址和对应的机器代码,中间的文本框中列出了当前指令的CS和IP。单击按钮,可以单步执行一条指令;单击按钮,可以一次执行完所有程序;单击按钮,可以重新回到第一条指令的位置处;单击按钮,可以重新加载另一个程序。 修改“emulator”对话框中文本框的内容,也可以观察其它段的内容,在图所示界面中,DS=0700H,若要察看该数据段中偏移地址为6000H位置处的内存单元内容,可以在文本框中输入0700:6000,显示结果如图所
5、示,中间部分依次列出从该地址开始的所有字节的内容。 在“emulator”对话框的底部,单击按钮,可以观察栈的内容;单击按钮,可以观察标志寄存器中标志位的内容。 在“emulator”对话框中,选择“view”菜单中的“memory”菜单项,也可以观察内存的情况。在“Random Access Memory”对话框中,可以修改文本框中的值可以确定所要观察的地址,该值由段基地址:段内偏移地址构成,如图所示,当前要观察的内存地址为(6000:0010)。在显示结果中,左边是逻辑地址,中间是从该地址的开始连续16个字节的内容,右边是每个字节对应的字符。在该对话框中,也可以直接修改存储器
6、单元的值,如图所示,从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 寻
7、址方式包括: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对话框中间的文本框中输入段基地址:段内偏移地址,可以观察其它逻辑段相应存储单
8、元的内容) (2)创建COM TEMPLATE程序,用以下程序段将一组数据压入PUSH堆栈区,然后通过三种不同方式出栈。观察栈的变化情况(提示:在emulator对话框中,单击按钮可以察看栈中内容)以及出栈后数据的变化情况,并把结果填入表 11中。程序段如下: 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 第二种出栈方式的指令序列(注:
9、替换掉第—种出栈方式的指令序列): POP AX POP BX POP CX POP DX 第三种出栈方式的指令序列(注:替换掉第二种出栈方式的指令序列): POP CX POP DX POP AX POP BX 表 11数据传送实验结果表格 寄存器的值 第一种出栈方式 第二种出栈方式 第三种出栈方式 (AX)= (BX)= (CX)= (DX)= (3)创建COM TEMPLATE程序,分别输入下列指令,按要求设置各寄存器及内存单元的值(提示:在“emulator”对话框中,可以直接修改寄
10、存器的值;选择“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]
11、 (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. 实验习题 指出下列指令的错误并加以改正
12、并在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)
13、加法指令,如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对话框中,单击按钮察看标志寄存器的值)。程序段及结果表格如表 12。 表 12算术逻辑运算实验结果表格 标志位 程序 CF ZF SF OF PF AF 程序段1 0 0 0 0 0 0 MOV AX,
14、1018H MOV SI, 230AH ADD AX, SI ADD AL, 30H MOV BX, 3FFH ADD AX,BX MOV [20H], 1000H ADD [20H], AX PUSH AX POP BX 程序段2 0 0 0 0 0 0 MOV AX, 0A0AH
15、 ADD AX, 0FFFFH MOV CX, 0FF00H ADC AX, CX SUB AX, AX INC AX OR CX, 0FFH AND CX, 0F0FH MOV [10H], CX 程序段3 0 0 0 0 0 0 MOV BL, 25H MOV BYTE PTR[10H], 4 M
16、OV AL, [10H] MUL BL 程序段4 0 0 0 0 0 0 MOV WORD PTR[10H],80H MOV BL, 4 MOV AX, [10H] DIV BL (2)用BX作为地址指针,从BX所指的内存单元[0010H]开始连续存入三个无符号数(10H、04H、30H),计算内存单元中这三个数的和,并将和放在0013H单元中,再求出这三个数的乘积,并将乘积存入0014单元中,写出完成此功能的COM
17、 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)假定要按高
18、地址到低地址的顺序进行清除操作(高地址从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 TEMPLA
19、TE程序,输入以下程序段,单步执行并记录标志位的变化情况(提示:在emulator对话框中,单击按钮可以察看标志寄存器的值)。程序段及结果表格如表 13。 表 13移位实验结果表格1 标志位 程序 CF ZF SF OF PF AF 程序段 0 0 0 0 0 0 MOV AX, 0 DEC AX ADD AX, 3FFFH ADD AX, AX NOT AX SUB AX, 3 OR
20、AX, 0FBFDH AND AX, 0AFCFH SHL AX,1 RCL AX,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
21、 TEMPLATE程序,输入以下程序段,单步执行并记录每一条指令对内存单元的影响结果(提示:在“emulator”对话框中,选择“view”菜单中的“memory”菜单项可以察看内存单元的值),分析结果并说明该程序段的功能是什么。程序段及结果表格如表 14。 表 14移位实验结果表格2 程序段 字单元[1A00H]= 字单元[1A02H]= MOV [1A00H], 0AA55H MOV [1A02H], 2AD5H SHL WORD PTR[1A02H],1 CMP [1A00H], 8000H CMC RCL WOR
22、D PTR[1A02H],1 RCL WORD PTR[1A00H],1 5. 实验习题 简要说明一般移位指令与循环移位指令之间的主要区别。 6. 实验报告要求 整理源程序段和运行结果,回答实验中的问题。 1.2.4 串操作指令 1. 实验目的 1)熟悉串操作指令的功能。 2)了解串操作指令的使用方法。 2. 实验设备 微型计算机、emu8086 3. 实验原理 串操作指令包括:1)串传送指令MOVS;2)串比较指令CMPS;3)串扫描指令SCAS;4)串装入指令LODS;5)串存储指令STOS。 4. 实验内容 (1)创建COM TEMPLAT
23、E程序,输入以下程序段,单步执行并根据结果回答后面的问题。 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 程序段执行
24、后: 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,20
25、00H 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开始的内存区域中(即传送
26、结束后,从DS:6100H开始的内存单元的内容为"gnirts a si sihT"),试编写COM TEMPLATE程序并上机验证。(提示:可以在数据区中直接输入字符串) 5. 实验习题 1)简要说明执行串操作指令之前应初始化哪些寄存器和标志位。 2)总结串操作指令的用途及使用方法。 6. 实验报告要求 整理源程序段和运行结果,对结果进行分析。 1.2.5 DOS功能调用 1. 实验目的 1) 掌握简单的DOS系统功能调用。 2. 实验设备 微型计算机、emu8086 3. 实验原理 本节要用到的DOS功能命令包括: 从键盘输入单个字符的语句如下: MOV AH
27、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)字符的输入和输出 从键盘读入一个小写字母,输出
28、字母表中倒数与该字母序号相同的那个字母。例如输入首字母a,则输出最后一个字母z,输入第4个字母d则输出倒数第4个字母w。 程序流程图如图 11所示。 开始 ′z′ – AL + ′a′ →AL 返回DOS 显示AL中的内容 从键盘输入字符到AL 图 11字符输入输出的程序流程图 程序框架如下: data segment pkey db "press any key...$" ends stack segment dw 128 dup(0) ends code segment start: ; set segment regis
29、ters: 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 21
30、h ends end start ; set entry point and stop the assembler. 编写EXE TEMPLATE程序(提示:计算’z’-al+’a’时,需要用sub指令),观察执行结果。 (2)字符串的输入和输出 从键盘输入一个字符串(以下说明中,假定键盘缓冲区的名字为KBUF,要显示的字符串变量名为STR),将输入的字符串传送给STR变量,在屏幕上显示STR变量中的内容。 程序流程图如图 12所示。 开始 将KBUF中的字符串传送到变量STR中: 1.字符串长度传送到CX 2.KBUF+2的偏移地址→SI,STR的偏移地址→DI
31、 3.循环传送字符串中的每个字符(循环次数在CX中) 显示INFO中的内容 返回DOS 从键盘输入字符串到KBUF 图 12字符串输入输出的程序流程图 程序框架如下: 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 a
32、x, 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
33、 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)整理源程序段和运
34、行结果。 2)说明DOS系统功能调用的10号功能对键盘缓冲区格式上有何要求。 3)DOS系统功能调用中的1、2、9、10号功能的输入输出参数有哪些?分别放在什么寄存器中? 4)总结汇编语言程序中如何实现字符和字符串的输入输出。 1.2.6 顺序程序 1. 实验目的 1)了解8086汇编程序的基本结构; 2)掌握顺序程序的基本设计方法。 2. 实验设备 微型计算机、emu8086 3. 实验原理 顺序程序是控制流仅有一个走向的程序,它主要用于解决一些无需进行判断分支,也无需循环执行的简单问题。 本节的实验内容与乘法和除法运算有关。无符号数乘法运算使用MUL指令,有符号数乘
35、法运算使用IMUL指令。乘法运算属于隐含操作数的运算,因此在使用乘法指令前,需要先将乘数放入AL(8位乘法)或AX(16位乘法)中。乘法指令执行后,乘积在AX(8位乘法)或DX:AX(16位乘法)中。无符号数除法运算使用DIV指令,有符号数除法运算使用IDIV指令。除法运算属于隐含操作数的运算,因此在使用除法指令前,需要先将被除数放入AX(8位除法)或DX:AX(16位除法)中。当除数为8位时,被除数应为16位;除数为16位时,被除数应为32位。对无符号数除法,当被除数字长不够时,高位部分可直接补0;而对有符号数除法,当被除数字长不够时,必须使用符号扩展指令进行扩展。除法运算执行后,结果在AX
36、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,将结果显示在屏幕上。 程序流程图如图 13。 [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(乘积备份
37、到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位
38、清0 3. AL的内容转换成ASCII码 4. 显示 开始 返回DOS 图 13顺序程序的程序流程图 程序框架如下: 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
39、 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
40、 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. 实验原理 分支程
41、序是根据不同条件执行不同处理过程的程序。分支程序的结构有两种:—种是二路分支,—种是多路分支。它们的共同特点是在满足某一条件时,将执行多个分支中的某—分支。 本节的实验内容与数值和ASCII码间的转换有关,由于字符′0′~′9′的ASCII码是30H~39H,因此将数值0~9转换成对应的ASCII码时,需要在其基础上加30H;由于字符′A′~′F′的ASCII码是41H~46H,因此将数值A~F转换成对应的ASCII码时,需要在其基础上加37H。另外,二进制数与十六进制数之间的关系是:每4位二进制数等于1位十六进制数。 在屏幕上显示单个字符的语句如下: MOV DL,<要显示的字符>
42、 MOV AH,2 INT 21H 4. 实验内容 从键盘输入一个十进制正整数N(10≥N≥99),将其转换成十六进制数,转换的结果显示在屏幕上。提示:键盘输入的内容都是ASCII码形式。 程序流程图如 图 14。 第一步:将ASCII码形式的两位十进制数转换成二进制数 1.(STR+2)-30H→AH(将十位数的ASCII码转换成BCD数) 2.(STR+3)-30H→AL(将个位数的ASCII码转换成BCD数) 3.AH*10+AL→AL(转换成二进制数保存在AL中) 第二步:将二进制数转换成十六进制数 AL中的高4位和低4位分别就是十六进制数的高位和低位 第
43、三步:显示结果的高4位 第四步:显示结果的低4位 结束 返回DOS 开始 从键盘输入一个两位的十进制数放入STR开始的键盘缓冲区中 图 14程序流程图 程序框架如下: data segment STR db 3,0,3 dup(0) MES db 'Input a decimal number(10~99):$' MES1 db 0ah,0dh,’Show decimal
44、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
45、中 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 entr
46、y 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. 实验原理 循环程序是把一个程序段重复执行多次的程序结构。循环程序包括三个部分:初
47、始化部分、循环体、循环控制部分。初始化部分用于对循环程序的参数(循环次数、控制条件、指针等)设置初值。循环体是要被重复执行的程序段。循环控制部分用于决定是否退出循环。循环控制指令可以是转移指令或LOOP指令。当已知循环次数或控制条件为ZF时,用LOOP指令控制循环是最简单的方法。 本节实验显示的图形可以分为上下两部分。对于上半部分图形,需要设置两层循环,其中外循环控制显示几行(初始为9,每次减1,减到0时结束);内循环控制当前行显示几个′*′(初值为1,每次加1)。对于下半部分图形,也需要设置两层循环,其中外循环控制显示几行(初始为9,每次减1,减到0时结束);内循环控制当前行显示几个空格(
48、初值为8,每次减1)和几个′*′(初值为1,每次加1)。 在屏幕上显示单个字符的语句如下: MOV DL,<要显示的字符> MOV AH,2 INT 21H 4. 实验内容 在屏幕上显示如下图形。 * ** *** **** ***** ****** ******* ******** ********* * ** *** **** ***** ****** ******* ******** ********* 程序的流程图如图 15所示。 开始 第一步:处理
49、上半部分图形 外循环计数器bl=9,每行星号个数bh=1 cl=bh 显示′*′ cl=cl-1 cl=0? N Y 显示回车,显示换行 bh=bh+1 bl=bl-1 bl=0? N 第二步:处理下半部分图形 外循环计数器 bl=9,每行空格个数 ch=8,每行星号个数 bh=1 Y cl=ch N 显示空格 cl=cl-1 cl=0? Y cl=bh 显示′*′ cl=cl-1 cl=0? N Y 显示回车,显示换行
50、 ch=ch-1 bh=bh+1 bl=bl-1 N bl=0? Y 结束 图 15程序流程图 程序的框架如下: 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=






