2.2 基本型实验项目

2.2.1数据传送指令使用

1.实验名称

数据传送指令实验

2.实验目的

掌握80X86汇编级指令系统中的数据传送类指令的使用

3.实验涉及的知识点和技能点

80X86汇编级指令系统

4.实验任务

(1)                                                 通过下述程序段的输入和执行来熟悉Turbo Debugger的使用,并在显示器上观察程序的执行情况。

    MOV  BL08H

    MOV  CLBL

    MOV  AX03FFH

    MOV  BXAX

    MOV  DS:[0020H]BX

(2)                                                 用以下程序段将一组数据压入PUSH堆栈区,然后通过三种不同的出方式出,查看出后数据的变化情况,并把结果填入表中。

    MOV  AX0102H

    MOV  BX0304H

    MOV  CX0506H

    MOV  DX0708H

    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

实验结果表格

 

第一种出方式

第二种出方式

第三种出方式

AX=

 

 

 

BX=

 

 

 

CX=

 

 

 

DX=

 

 

 

(3)                                                 按如下在TD中设置各寄存器及存储单元的内容:

BX0010HSI0001H

[60010H]12H[60011H]34H[60012H]56H[60013H]78H[60120H]0ABH[60121H]0CDH[60122H]0EFH

指出下列各条指令执行后AX中的内容,并验证答案:

MOV  AX1200H

MOV  AXBX

MOV  AX[0120H]

MOV  AX[BX]

MOV  AX0110H[BX]

MOV  AX[BX][SI]

MOV  AX0110H[BX][SI]

(4)                                                 DS:1000H字节存储单元中的内容送到DS:2020H单元中存放。试分别用8086的直接寻址、寄存器间接寻址、变址寻址、寄存器相对寻址传送指令编写程序段,并验证答案。

(5)                                                 AX的内容为1111HBX的内容为2222HDS:0010H单元的内容为3333H。将AX的内容与BX的内容交换,然后再将BX的内容与DS:0010H单元的内容进行交换。试编写程序段,并验证答案。

(6)                                                 存储器的内容如图所示。要求将DS:1000H中的0EEFFH传送到AXES:2000H中的0CCDDH传送到BX,请写出相关指令并验证答案。

 

 

 

 

 


图 存储器示意图

5.实验条件

(1)                                                 PC系列微机一台。

(2)                                                 汇编语言编程环境(TD)

6.实验分析

(1)                                                 TD的使用

上述实验如果在TD中完成,可以参照下列操作步骤。

1)                                              启动Turbo DebuggerTD.EXE

2)                                              使CPU窗口为当前窗口

3)                                              输入程序段

利用↑ 、↓方向键移动光条来确定输入位置,然后从光条所在的地址处开始输入,强烈建议把光条移到CS:0100H处开始输入程序。

光条处直接键入练习程序段指令,键入时屏幕上会弹出一个输入窗口,这个窗口就是指令的临时编辑窗口。每输入完一条指令,按回车,输入的指令即可出现在光条处,同时光条自动下移一行,以便输入下一条指令。例如:

  MOV  BL08H    (↙表示回车键)

  MOV  CLBL

窗口中前面曾经输入过的指令均可重复使用,只要用方向键把光标定位到所需的指令处,按回车即可。

4)                                              执行程序段

①用单步执行的方法执行程序段

使IP寄存器指向程序段的开始处。方法如下:

光条移到程序段开始的第一条指令处,按Alt-F10,弹出CPU窗口的局部菜单,选择“New CS:IP”项,按回车键,这时CSIP寄存器(在CPU窗口中用4符号表示,4符号指向的指令就是当前要执行的指令)就指向了当前光条所在的指令。

另一种方法是直接修改IP的内容为第一条指令的偏移地址:

F7Trace into)或F8(为Step over)单步执行程序段。每按一次F7F8键,就执行一条指令。按F7F8键直到程序段的所有指令都执行完为止,这时光条停在程序段最后一条指令的下一行上。(F7F8键的区别是:若执行的指令是CALL 指令,F7会单步执行进入到子程序中,而F8则会把子程序执行完,然后停在CALL指令的下一条指令处。)

②用设置断点的方法执行程序段

光条移到程序段最后一条指令的下一行,按F2键设置断点。

用①中的方法把使IP寄存器指向程序段的开始处。

F4键或F9键运行程序段,CPUIP指针开始执行到断点位置停止。

5)                                              检查各寄存器和存储单元的内容

寄存器窗口显示在CPU窗口的右部,寄存器窗口中直接显示了各寄存器的名字及其当前内容。在单步执行时可随时观察寄存器内容的变化。

存储器窗口显示在CPU窗口的下部,若要检查存储单元的内容,可连续按Tab键使存储器窗口为当前窗口,然后按Alt-F10键,弹出局部菜单。选择GOTO项,然后输入要查看的存储单元的地址,如DS:20H↙,存储器窗口就会从该地址处开始显示存储区域的内容。注意,每行显示8个字节单元的内容。

(2)                                                 数据传送类指令

1)                                              通用数据传送指令,如MOV,PUSH,POP,XCHG,CBW,CWD

2)                                              目标地址传送指令,如LDS,LES

3)                                              标志传送指令,如LAHF,SAHF,PUSHF,POPF

4)                                              输入输出指令,如IN,OUT,LEA

7.思考问题

(1)                                                 指出下列指令的错误并加以改正。

MOV  [BX][SI]

MOV  AHBX

MOV  AX[SI][DI]

MOV  BYTE PTR[BX]2000H

MOV  CSAX

MOV  DS2000H

8.建议学时

课内2学时,外加课外2学时。

2.2.2算术逻辑运算指令使用

1.实验名称

算术逻辑运算指令

2.实验目的

掌握80X86汇编级指令系统中的算术逻辑运算类指令的使用

3.实验涉及的知识点和技能点

80X86汇编级指令系统

4.实验任务

(1)                                                 执行下列各程序段并将每步结果记录在表中。

表 实验结果记录表

标志位

CF

ZF

SF

OF

PF

AF

程序段1

0

0

0

0

0

0

MOV  AX, 1018H

 

 

 

 

 

 

MOV  SI, 230AH

 

 

 

 

 

 

ADD  AX, SI

 

 

 

 

 

 

ADD  AL, 30H

 

 

 

 

 

 

MOV  DX, 3FFH

 

 

 

 

 

 

ADD  AXBX

 

 

 

 

 

 

MOV  [20H], 1000H

 

 

 

 

 

 

ADD  [20H], AX

 

 

 

 

 

 

PUSH AX

 

 

 

 

 

 

POP  BX

 

 

 

 

 

 

程序段2

0

0

0

0

0

0

MOV  AX, 0A0AH

 

 

 

 

 

 

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

 

 

 

 

 

 

MOV  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)开始连续存入三个无符号数(10H04H30H),接着计算内存单元中的这三个数之和,和放在0013H单元中,再求出这三个数之积,积放0014单元中。写出完成此功能的程序段并验证结果。

(3)                                                 写出完成下述功能的程序段。验证写出的程序段,程序运行的最后结果(AX)?

1)                                            传送15HAL寄存器;

2)                                            再将AL的内容乘以2

3)                                            接着传送15HBL寄存器;

4)                                            最后把AL的内容乘以BL的内容。

5)                                            最后把商存入字节单元DS:1003H中。

(4)                                                 下面的程序段用来清除数据段中从偏移地址0010H开始的12个字存储单元的内容(即将零送到这些存储单元中去)。

1)                                            将第4条比较指令语句填写完整(划线处)。

MOV  SI0010H

NEXT: MOV  WORD PTR[SI]0

ADD  SI2

CMP  SI      

JNE  NEXT

HLT

2)                                            假定要按高地址到低地址的顺序进行清除操作(高地址从0020H开始),则上述程序段应如何修改?

上机验证以上两个程序段并检查存储单元的内容是否按要求进行了改变。

5.实验条件

(1)                                                 PC系列微机一台。

(2)                                                 汇编语言编程环境(TD)

6.实验分析

(1)                                                 TD的使用

上述实验如果在TD中完成,可以参照下列操作步骤。

1)                                              进入Turbo Debugger,在CPU窗口中输入程序段。

2)                                              在标志窗口中把各标志位清零。

3)                                              CPU窗口中把IP指针指向程序段开始处。

4)                                              步运行程序,在表中记录每条指令执行后的标志位变化情况。

5)                                              根据记录的数据分析每条指令执行后的结果及其对标志位的影响。

(2)                                                 算术运算指令

1)                                              加法指令,如ADD,ADC,INC

2)                                              减法指令,如SUB,SBB,DEC,NEG,CMP

3)                                              乘法指令MUL,IMUL

4)                                              除法指令,如DIV,IDIV

(3)                                                 逻辑运算指令

AND,OR,NOT,XOR,TEST

7.思考问题

(1)                                                 简要说明ADDSUBANDOR指令对标志位的影响。

8.建议学时

课内2学时,外加课外2学时。

2.2.3移位操作指令使用

1.实验名称

移位操作指令

2.实验目的

掌握80X86汇编级指令系统中的移位操作类指令的使用

3.实验涉及的知识点和技能点

80X86汇编级指令系统

4.实验任务

(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   AX, 0FBFDH

 

 

 

 

 

 

AND  AX, 0AFCFH

 

 

 

 

 

 

SHL  AX1

 

 

 

 

 

 

RCL  AX1

 

 

 

 

 

 

(2)                                                 写出完成下述功能的程序段。验证写出的程序段,程序运行后的商=?

1)                                            传送数据2058HDS:1000H单元中,数据12HDS:1002H单元中;

2)                                            DS:1000H单元中的数据传送到AX寄存器;

3)                                            AX寄存器的内容算术右移二位;

4)                                            再把AX寄存器的内容除以DS:1002H字节单元中的数;

5)                                            最后把商存入字节单元DS:1003H中。

(3)                                                 输入并单步运行表中的程序段,观察每一条指令的执行结果,并将结果填入表右边的空格中。分析结果,说明本程序段的功能是什么?

表 实验结果表

程序段

字单元(1A00H)=

字单元(1A02H)=

MOV  [1A00H], 0AA55H

 

 

MOV  [1A02H], 2AD5H

 

 

SHL  WORD PTR[1A02H],1

 

 

CMP  [1A00H], 8000H

 

 

CMC

 

 

RCL  WORD PTR[1A02H],1

 

 

RCL  WORD PTR[1A00H],1

 

 

5.实验条件

(1)                                                 PC系列微机一台。

(2)                                                 汇编语言编程环境(TD)

6.实验分析

(1)                                                 移位指令

1)                                              非循环移位指令,如SAL,SAR,SHL,SHR

2)                                              循环移位指令,如ROL,ROR,RCL,RCR

7.思考问题

(1)                                                 简要说明一般移位指令与循环移位指令之间的主要区别。

8.建议学时

课内2学时,外加课外2学时。

2.2.4串操作指令使用

1.实验名称

串操作指令

2.实验目的

掌握80X86汇编级指令系统中的串操作类指令的使用

3.实验涉及的知识点和技能点

80X86汇编级指令系统

4.实验任务

(1)                                                 输入以下程序段并运行之,根据结果回答后面的问题。

CLD

MOV  DI1000H

MOV  AX55AAH

MOV  CX10H

REP   STOSW

程序段执行后,从DS:1000H开始的16个字单元的内容是什么?DI = CX= ?,并解释其原因。

(2)                                                 在上题的基础上,再输入以下程序段并运行之,回答后面的问题。

MOV  SI1000H

MOV  DI2000H

MOV  CX20H

REP   MOVSB

程序段执行后,从DS:2000H开始的16个字单元的内容是什么?SI = DI = CX = ?,并分析之。

(3)                                                 在以上两题的基础上,再分别输入以下三个程序段并运行之。

程序段1

MOV  SI1000H

MOV  DI2000H

MOV  CX10H

REPZ  CMPSW

程序段1执行后,ZF=?根据ZF的状态,你认为两个串是否比较完了?SI = DI = CX = ?,并分析之。

程序段2

MOV  [2008H]4455H

MOV  SI1000H

MOV  DI2000H

MOV  CX10H

REPZ  CMPSW

程序段2执行后,ZF=? 根据ZF的状态,你认为两个串是否比较完了?SI = DI = CX = ?,并分析之。

程序段3

MOV  AX4455H

MOV  DI2000H

MOV  CX10H

REPNZ  SCASW

程序段3执行后,ZF=? 根据ZF的状态,你认为在串中是否找到了数据4455HSI = DI = CX = ?,并分析之。

(4)                                                 DS:1000H开始存放有一个字符串This is a string,要求把这个字符串从后往前传送到DS:2000H开始的内存区域中(即传送结束后,从DS:2000H开始的内存单元的内容为gnirts a si sihT),试编写程序段并上机验证之。

5.实验条件

(1)                                                 PC系列微机一台。

(2)                                                 汇编语言编程环境(TD)

6.实验分析

(1)                                                 串操作指令

1)                                            串传送指令,如MOVS

2)                                            串比较指令,如CMPS

3)                                            串扫描指令,如SCAS

4)                                            串装入指令,如LODS

5)                                            串存储指令,如STOS

7.思考问题

(1)                                                 简要说明执行串操作指令之前应初始化哪些寄存器和标志位。

(2)                                                 总结串操作指令的用途及使用方法。

8.建议学时

课内2学时,外加课外2学时。

2.2.5DOS/BIOS功能调用认知

1.实验名称

DOS功能调用认知

2.实验目的

掌握80X86汇编级指令系统的使用;

掌握基本的DOS/BIOS功能调用中字符及字符串输入和输出。

3.实验涉及的知识点和技能点

80X86汇编级指令系统、常用DOS/BIOS功能调用。

4.实验任务

(1)                                                 从键盘读入一个小写字母,输出字母表中倒数与该字母序号相同的那个字母。例如输入首字母a,则输出最后一个字母z,输入第4个字母d则输出倒数第4个字母w

(2)                                                 从键盘输入一个字符串(以下说明中,假定键盘缓冲区的名字为KBUF,要显示的字符串变量名为STR),将输入的字符串传送给STR变量后,再在屏幕上显示出来。

5实验条件

(1)                                                 PC系列微机一台。

(2)                                                 汇编语言编程环境(MASMTD)

6.实验分析

(1)                                                 DOS功能命令

1)                                                      从键盘输入单个字符可以使用以下两条指令:

MOV  AH1

        INT   21H

        以上两条指令执行后,(AL=从键盘输入的字符

2)                                                      在屏幕上显示单个字符可以使用以下三条指令:

MOV  DL<要显示的字符>

MOV  AH2

INT   21H

3)                                                      在程序结束处使用以下两条指令即可返回操作系统:

       MOV  AH4CH

       INT   21H

注意:源程序中的所有语法符号都必须是半角符号,而且不允许汉字字符。

4)                                                      在屏幕上显示字符串可以使用以下三条指令:

LEA  DX<字符串变量名,字符串必须以字符$作为结束>

MOV  AH9

INT   21H

5)                                                      从键盘上输入字符串可以使用以下三条指令:

LEA  DX<键盘缓冲区名>

MOV  AH0AH

INT   21H

(2)                                                 任务1程序流程图

 

 

 

 

 

 

 

 

(3)                                                 任务2程序流程图

 

 

 

 

 

 

 

 

 

 

 


(4)                                                 任务1程序框架

CSEG  SEGMENT

        ASSUME CS:CSEG

START: 

从键盘输入一个字符的指令序列

 

 
 

 

根据流程图中转换算法编制的指令序列

 

用于显示结果的指令序列

 
 

 

 


KEY:    MOV  AH1          ;判断是否有按键按下?

INT  16H            ;(为观察运行结果,使程序有控制地退出)

JZ   KEY            ;(注:这三条指令可以省略)

返回DOS的指令序列

 

 
 


CSEG  ENDS                ;代码段结束

       END  START         ;程序结束  

(5)                                                 任务2程序框架

DSEG  SEGMENT

KBUF  DB 20, 0, 20 DUP(20H)

STR0   0DH, 0AH

STR    DB 20 DUP(20H), ’$’

DSEG    ENDS

CSEG  SEGMENT

        ASSUME CS:CSEG, DS:DSEG

START: 

       MOV  AXDSEG

       MOV  DSAX

 

 

 


KEY:    MOV  AH1           ; 判断是否有按键按下

INT  16H             ; (为观察结果并使程序有控制地退出)

JZ   KEY             ; (这三条指令可以省略)

返回DOS的指令序列

 

 
 


CSEG  ENDS                ; 代码段结束

       END  START         ; 程序结束  

7思考问题

(1)                                                 如果要在程序中加入显示提示字符串Please input a lowercase letterThe inverse letter is:”,应如何修改程序

(2)                                                 如果要在显示结果中加入提示Please input a stingThe string you input  is:”,应如何修改程序

(3)                                                 总结用DOS功能实现字符和字符串输入输出的方法。

8.建议学时

课内2学时,外加课外2学时。

2.2.6顺序程序设计

1.实验名称

顺序程序设计

2.实验目的

了解汇编语言程序设计的一般过程;

掌握基本结构程序设计中的顺序程序设计。

3.实验涉及的知识点和技能点

源程序结构、汇编语言程序设计的一般过程、基本结构程序设计

4.实验任务

(1)                                                 NUM变量中定义了5个有符号数(字节类型),分别是U= 09HV=16HW=02HX=03HY=05H,计算(U+V-W*X/Y,将结果显示在屏幕上。

5.实验条件

(1)                                                 PC系列微机一台。

(2)                                                 汇编语言编程环境(MASMTD)

6.实验分析

(1)                                                 顺序程序

顺序程序是控制流仅有一个走向的程序,它主要用于解决一些无需进行判断分支,也无需循环执行的简单问题。

(2)                                                 MASM的使用

源程序编制完后,先静态检查,无误后,对源程序进行汇编连接,生成可执行文件。先将程序在DOS下运行,如正确,则改变输入的数值反复验证,如不正确,则将程序调入TD中进行调试。

(3)                                                 程序流程图

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


(4)                                                 乘法运算

无符号数乘法运算使用MUL指令,有符号数乘法运算使用IMUL指令。

乘法运算属于隐含操作数的运算,因此在使用乘法指令前,需要先将乘数放入AL8位乘法)或AX16位乘法)中。乘法指令执行后,乘积放在AX8位乘法)或DX:AX16位乘法)中。

(5)                                                 除法运算

无符号数除法运算使用DIV指令,有符号数除法运算使用IDIV指令。

除法运算属于隐含操作数的运算,因此在使用除法指令前,需要先将被除数放入AX8位除法)或DX:AX16位除法)中。注意,当除数为8位时,被除数应为16位;除数为16位时,被除数应为32位。对无符号数除法,当被除数字长不够时,高位部分可直接补0;而对有符号数除法,当被除数字长不够时,必须使用符号扩展指令进行扩展。除法运算执行后,结果放在AX8位除法)或DX:AX16位除法),其中AL8位除法)或AX16位除法)中是商,AH8位除法)或DX16位除法)中是余数。

(6)                                                 程序框架

DSEG  SEGMENT

    NUM   DB  09H16H04H17H05H  ; 定义UVWXY

DSEG  ENDS

CSEG  SEGMENT

        ASSUME  CS:CSEGDS:DSEG

START: MOV  AXDSEG

       MOV  DSAX

计算(U+V-W*X/Y的指令序列(第一、二、三步)

 

显示结果的指令序列(第四、五步)

 

 

 

返回DOS的指令序列

 

 
 

 

 

 


CSEG  ENDS

      END  START 

7.思考问题

(1)                                                 U=0ABHV=0EFHW=12HX=10HY=05H,则如何修改程序才能使结果正确。

8.建议学时

课内2学时,外加课外2学时。

2.2.7分支程序设计

1.实验名称

分支程序设计

2.实验目的

了解汇编语言程序设计的一般过程;

掌握基本结构程序设计中的分支程序设计。

3.实验涉及的知识点和技能点

源程序结构、汇编语言程序设计的一般过程、基本结构程序设计

4.实验任务

(1)                                                 从键盘输入的一个十进制正整数N10N99),将其转换成十六进制数,转换的结果显示在屏幕上。注意,键盘输入的内容都是ASCII码形式。

5.实验条件

(1)                                                 PC系列微机一台。

(2)                                                 汇编语言编程环境(MASMTD)

6.实验分析

(1)                                                 分支程序

分支程序是根据不同条件执行不同处理过程的程序。分支程序的结构有两种:—种是二分支,—种是多分支。它们的共同特点是在满足某一条件时,将执行多个分支中的某—分支。

(2)                                                 程序流程图

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(3)                                                 数字与字符的转换

字符0~9ASCII码是30H~39H,即在数值0~9的基础上加30H

字符A~FASCII码是41H~46H,即在数值A~F的基础上加37H

(4)                                                 程序框架

DSEG  SEGMENT

STR    DB  3, 0, 3 DUP(?)

MES DB  Input a decimal number10~99):’, 0AH, 0DH, ’$’

MES1   DB  0AH, 0DH,'Show decimal number as hex$'

DSEG  ENDS

CSEG  SEGMENT

    ASSUME  CS:CSEG, DS:DSEG

START:  MOV  AXDSEG

        MOV  DSAX

显示字符串:“Input a decimal number10~99):”

 
         

从键盘输入一个两位的十进制数(ASCII码形式)

 

 

ASCII码形式的十进制数转换成十六进制数(第一、二步)

 

显示字符串:“Show decimal number as hex:”

 

显示转换后的十六进制结果(第三、四步)

 
 

 

 

 

 


KEY:     MOV  AH1         ; 判断是否有按键按下?

INT  16H            ; (为观察结果,并使程序有控制地退出)

JZ   KEY           ; (注:这三条指令可以省略)

返回DOS的指令序列

 

 
 


CSEG  ENDS

       END  START

7.思考问题

(1)                                                 如果输入的数在0~99范围内,则如何修改程序才能使结果正确。

(2)                                                 如果可以输入负整数,则如何修改程序才能使结果正确。

(3)                                                 简要说明汇编语言程序设计的步骤和每个步骤使用哪种软件工具,生成什么类型的文件。

8.建议学时

课内2学时,外加课外2学时。

2.2.8循环程序设计

1.实验名称

循环程序设计

2.实验目的

了解汇编语言程序设计的一般过程;

掌握基本结构程序设计中的循环程序设计。

3.实验涉及的知识点和技能点

源程序结构、汇编语言程序设计的一般过程、基本结构程序设计

4.实验任务

BUFFER开始的内存单元中,顺序存放着N(N>9)有符号字节数据,编写程序从中查找最大和最小的数,置于MAXMIN单元中。

5.实验条件

(1)                                                 PC系列微机一台。

(2)                                                 汇编语言编程环境(MASMTD)

6.实验分析

(1)                                                 循环程序

循环程序是把一个程序段重复执行多次的程序结构。循环程序包括三个部分:初始化部分、循环体、循环控制部分。

初始化部分用于对循环程序的参数(循环次数、控制条件、指针等)设置初值。循环体是要被重复执行的程序段。循环控制部分用于决定是否退出循环。循环控制指令可以是转移指令或LOOP指令。当已知循环次数或控制条件为ZF时,用LOOP指令控制循环是最简单的方法。

(2)                                                 程序流程图

查找最大和小数的方法是,先假定第一个数是当前最大和最小的数,然后从第二个数开始,依次取出数据与当前最大和小数进行比较,若数据大于当前最大数,则用数据替换当前最大数;否则,若数据小于当前小数,则用数据替换当前小数,经N-1次比较后,程序结束,相应的程序流程如图所示。

7.思考问题

(1)                                                 若实验要求改为找绝对值最大和最小的数,编写程序实现。

8.建议学时

课内2学时,外加课外2学时。

2.2.9子程序结构程序设计

1.实验名称

子程序结构程序设计

2.实验目的

了解汇编语言程序设计的一般过程;

掌握基本结构程序设计中的子程序设计。

3.实验涉及的知识点和技能点

源程序结构、汇编语言程序设计的一般过程、基本结构程序设计和子程序设计与调用

4.实验任务

(1)                                                 从内存ARY开始的数据区中存放着由N无符号字数据组成的一维数组,编写程序对这N元素的数组求和,结果扩展为32位,存于SUM开始的2个字单元中。要求:数组求和用一个子程序(过程)实现;主程序通过调用子程序实现数组求和,调用时,入口参数(数组起始地址、数组长度)和出口参数(求和结果)均通过寄存器传递;用调试环境验证其正确性。

(2)                                                 编写计算Ackerman函数的程序。Ackerman函数定义如下:

5.实验条件

(1)                                                 PC系列微机一台。

(2)                                                 汇编语言编程环境(MASMTD)

6.实验分析

(1)                                                 任务1流程图

假定主程序通过寄存器BXCX分别将数组的起始地址和长度信息传递给子程序;子程序通过计数循环对数组元素累加求和,计算结果通过DX:AX寄存器对返回主程序,则相应程序流程如图所示。

(2)                                                 任务2分析

Ackerman函数是一个采用递归定义的函数,适合于用递归子程序来实现。

计算ack(mn)本身是一个子程序。为计算ack(m-11),可使用参数m=m-1n=1递归调用计算ack(mn)的子程序。同样,为计算ack(m-1ack(mn-1)),要进行两次递归调用,第一次递归调用计算ack(mn-1),第二次递归调用计算ack(m-1ack(mn-1)),只是每次调用时使用的参数不同而已。

设计递归子程序时,必须保证每次调用都不破坏以前调用时所使用的参数和中间结果。所以,主程序与子程序间的参数传递,一般要通过堆栈传递。此函数计算需压入3个参数:nm和结果返回地址(Result_addr)。若将子程序定义成远过程,则进入子程序后,顶结构如下(假定参数压顺序为: Result_addrmn)

    Frame  STRUC                        ;定义调用结构

      SAVE_BP       DW  ?               BP(为使用BP,由子程序压保护)

      SAVE_CS_IP    DW  2 DUP (?)       ;返回地址

      N             DW  ?               ;参数N

      M             DW  ?               ;参数M

      Result_addr   DW  ?               ;结果返回地址

    Frame  ENDS

    于是,进入子程序并压保护BP寄存器后,可用以下方法引用参数:

        MOV   BPSP                    BP为调用结构指针(指向)

        MOV   SI[BP].Result_addr          取结果存放地址

        MOV   AX[BP].M                ;取参数M

        MOV   BX[BP].N                ;取参数N

7.思考问题

(1)                                                 若实验任务(1)的参数传递改为通过堆栈传递,编写程序实现。

(2)                                                 若实验任务(1)的参数传递改为通过地址表传递,编写程序实现。

(3)                                                 编写用递归子程序计算N!的函数。

8.建议学时

课内4学时,外加课外48学时

2.3 综合型实验项目

2.3.1排序程序设计

1.实验名称

循环程序设计

2.实验目的

掌握冒泡排序算法的程序实现;

掌握常用的DOS/BIOS功能调用。

3.实验涉及的知识点和技能点

三种基本结构程序设计、常用DOS/BIOS功能调用。

4.实验任务

在屏幕上显示提示信息“Please input 10 numbers:”,提示用户输入10个数(数的范围在099之间),然后从键盘上读入这10个数。接着对这10个数从小到大进行排序,并统计05960798099的数各有多少。最后在屏幕上显示排序后的数(每个数之间用逗号分隔)并显示统计的结果。显示格式如下:

Sorted numbers: xx,xx,xx,xx,xx,xx,xx,xx,xx,xx

0-59: xx

60-79: xx

80-99: xx

5.实验条件

(1)                                                 PC系列微机一台。

(2)                                                 汇编语言编程环境(MASMTD)

6.实验分析

(1)                                                 程序流程图


(2)                                                 冒泡排序

对数据进行排序的程序段可以使用冒泡排序法,排序过程如下:

从第一个数开始依次进行相邻两个数的比较,即第一个数与第二个数比,第二个数与第三个数比,…,比较时若两个数的次序对(即符合排序要求),则不做任何操作;若次序不对,就交换这两个数的位置。经过这样一遍全表扫描比较后,最大的数放到了表中第N元素的位置上。在第一遍扫描中进行了(N-1)次比较。用同样的方法再进行第二遍扫描,这时只需考虑(N-1)个数之间的(N-2)次比较,扫描完毕后次大的数放到了表中第(N-1元素的位置上,…,依此类推,在进行了(N-1)遍的扫描比较后则完成排序。

冒泡法最大可能的扫描遍数为(N1)。但是,往往有的数据表在第i遍(i<N1)扫描后可能已经成序。为了避免后面不必要的扫描比较,可在程序中引入一个交换标志,标志位为1,表示比较过程发生了交换;为0表示比较过程未发生交换。若在某一遍扫描比较中,一次交换也未发生,则表示数据已按序排列,在这遍扫描结束时,就停止程序循环,结束排序过程。

上述冒泡算法可用双重循环实现,内循环用计数控制一遍扫描的比较次数,外循环用状态控制是否已排序好。相应程序流程如图所示。

(3)                                                 提示信息的显示

提示信息需预先用DB伪指令在数据段中进行定义。提示信息字符串要用引号起来,并用美元符‘$’作为字符串的结束。显示时将此提示信息字符串的偏移地址送入DX中,用9号系统功能调用即可。程序段举例如下:

数据段中:

    MESSAGE  DB  'Please input 10 numbers:'0DH0AH'$'

程序段中:

    MOV  DXOFFSET MESSAGE     ;或LEA  DX, MESSAGE

    MOV  AH9

    INT  21H

(4)                                                 接收键入的字符串

接收键入的字符可用DOS功能调用的0AH号功能。在使用此功能调用前,需要在数据段定义键盘输入缓冲区,缓冲区第—字节存放它能保存的最大字符数,第二个字节存放实际输入的字符数(由0AH号功能负责填入),用户从键盘输入的字符串从第三个字节放起,用户以回车键结束本次输入。如果输入的字符数超过所定义的键盘缓冲区所能保存的最大字符数,0AH号功能将拒绝接收多出的字符。输入结束时的回车键也作为一个字符(0DH)放入字符缓冲区,因此设置的缓冲区应比希望输入的字符数多一个字节。在调用0AH号功能前需将键盘输入缓冲区的偏移地址放到DX寄存器中。程序段举例如下(假定最多输入二个字符):

数据段中:

    KB_BUF  DB  3           ;定义可接收最大字符数(包括回车键)

    ACTLEN  DB  ?           ;实际输入的字符数

    BUFFER  DB  3  DUP(?)   ;输入的字符放在此区域中

注:上述键盘缓冲区也可定义为

KB_BUF  DB  3, ?, 3 DUP(?)

但要取出实际输入的字符个数和输入的字符就必须使用相对寻址。

程序段中:

MOV  DX, OFFSET KB_BUF

MOV  AH, 0AH

INT  21H

(5)                                                 宏指令的定义与调用

在显示提示信息后和输入数据后,都需要回车换行,在这里我们用一个宏指令CRLF来实现。注意,宏指令CRLF中又调用了另外一个带参数的宏指令CALLDOS。宏指令一般要定义在程序的最前面。

宏定义:

CALLDOS MACRO FUNCTION       ;定义宏指令CALLDOS

MOV  AH, FUNCTION

INT  21H

ENDM                 ;宏定义结束

;

CRLF  MACRO                 ;定义宏指令CRLF

MOV  DL0DH          ;回车

CALLDOS 2             ;2号功能调用——显示字符

MOV  DL0AH          ;换行

CALLDOS 2

ENDM                  ;宏定义结束

CRLF宏指令用2DOS功能调用(显示一个字符)显示回车符与换行符的方法来实现回车换行。2DOS功能在显示回车符与换行符时实际上只是把光标移到下一行的开始,而并非把0DH0AH显示在屏幕上。

宏调用:在程序中凡是需要进行回车换行的地方只要把CRLF当作一条无操作数指令直接插入该处即可。在程序中若要使用CALLDOS宏指令,需要在CALLDOS宏指令后代入实参数(CALLDOS的实参数为功能调用的功能号)。

(6)                                                 程序框架

为了便于排序和统计,从键盘输入的数据先转换成二进制数存储,在最后显示结果前再把数据转换成ASCII码。

编程提示中介绍的宏CALLDOSCRLF放在此处

 
DATA      SEGMENT

;提示信息字符串

MESSAGE   DB  'Please input 10 numbers:',0DH,0AH,'$'

;键盘缓冲区

KB_BUF    DB  3            ;定义可接收最大字符数(包括回车键)

ACTLEN    DB  ?            ;实际输入的字符数

BUFFER    DB  3  DUP(?)    ;输入的字符放在此区域中

;数据及统计结果

NUMBERS   DB  10 DUP(?)    ;键入的数据转换成二进制后放在此处

LE59      DB  0            ;059的个数

GE60      DB  0            ;6079的个数

GE80      DB  0            ;8099的个数

;显示结果的字符串

SORTSTR   DB  'Sorted numbers:'

SORTNUM   DB  10 DUP(20H,20H,','),0DH,0AH

MESS00    DB  ' 0-59:',30H,30H,0DH,0AH

MESS60    DB  '60-79:',30H,30H,0DH,0AH

MESS80    DB  '80-99:',30H,30H,0DH,0AH,'$'

DATA      ENDS

;

CODE      SEGMENT

ASSUME  CS:CODE, DS:DATA

START:    MOV  AX, DATA

          MOV  DS, AX

1.显示MESSAGE提示信息

 
 

 


           MOV  CX, 10                  ;共读入10个数据

           LEA  DI, NUMBERS             ;设置数据保存区指针

2.从键盘读入一个数据,转换成二进制数存入DI所指向的内存单元

 
LP1:      

 

 

           INC  DI                      ;指向下一个数据单元

           CRLF                         ;在下一行输入

           LOOP LP1                     ;直到10个数据都输入完

3.NUMBERS中的10个数据排序

 

4.NUMBERS中的10个数据进行统计,结果放在GE80GE60LE59

 

 
 

 

 

5.把排序后的10个数据转换成ASCII码依次存入SORTNUM字符串中

 

 

6.GE80GE60LE59中的统计结果转换成ASCII码存入MESS80MESS60MESS00字符串中

 

 
 

 

 

 

 


          LEA  DX, SORTSTR              ;显示排序和统计的结果

          MOV  AH9

          INT  21H

          MOV  AH, 4CH

          INT  21H

CODE      ENDS

          END  START

7.思考问题

(1)                         从键盘输入任意一个字符串,统计其中AZ字符出现的次数(不分大小写,没出现次数就记为0),并把结果显示在屏幕上。显示格式如下:

A: xx

B: xx

Z: xx

(2)                         从键盘分别输入两个字符串,若第二个字符串包含在第一个字符串中就显示‘MATCH’,否则显示‘NO MATCH’。

(3)                         6×16列的格式顺序显示ASCII码为20H7FH之间的所有字符,即每16个字符为一行,共6行。每行中相邻的两个字符之间用空格字符分隔开。试编写程序段并上机运行验证。提示:程序段包括两层循环,内循环次数为16,每次内循环显示一个字符和一个空格字符;外循环次数为6,每个外循环显示一行字符并显示一个回车符(0DH)和一个换行符(0AH)。

8.建议学时

课内2学时,外加课外2学时。

2.3.2码制转换程序设计

1.实验名称

码制转换程序设计

2.实验目的

掌握码制转换算法的程序实现;

掌握常用的DOS/BIOS功能调用。

3.实验涉及的知识点和技能点

三种基本结构程序设计、常用DOS/BIOS功能调用。

4.实验任务

从键盘输入不多于5位的ASCII码十进制数(<65536),以回车键结束。将其转换为16位二进制数,然后任选以下一种方式,将转换好的数据从屏幕输出:将转换好的数据再以十进制形式从屏幕输出;将转换好的数据以二进制形式从屏幕输出;将转换好的数据以十六进制形式从屏幕输出。

5.实验条件

(1)                                                 PC系列微机一台。

(2)                                                 汇编语言编程环境(MASMTD)

6.实验分析

(1)                                                 程序流程图

若要将存于BUF缓冲区中的ASCII码数转换成二进制数,相应的转换程序流程如图所示。


(2)                                                 输出信息的显示

若要将转换结果以十进制形式显示,可以通过“除10取余”的方法得到由低到高的各位数,再转换成对应的ASCII码。

若要用二进制形式显示转换结果,可按从高到低的顺序,用移位指令将每位二进制码转换成对应的ASCII码。

若要用十六进制形式显示,可按从高到低的顺序,用移位指令将每4位二进制码转换成对应的ASCII码。

(3)                                                 接收键入的字符串

从键盘输入不多于5位的ASCII码十进制数可用DOS0AH号功能调用实现,方法如下:

        BUF   DB  6,?         ;指定最多输入6位数(含回车符)

        ASC   DB  6 DUP(?)          ;存放输入数据

           

        LEA     DXBUF

        MOV     AH0AH

        INT     21H

实际输入ASCII码数的位数存于BUF+1单元,ASCII码数按从高到低的顺序存于ASC开始的存储单元。

7.思考问题

(1)                                                 若循环结束改为计数控制,程序应如何修改?

8.建议学时

课内2学时,外加课外2学时。

2.3.3字符搜索程序设计

1.实验名称

字符搜索程序设计

2.实验目的

掌握字符搜索算法的程序实现;

掌握常用的DOS/BIOS功能调用。

3.实验涉及的知识点和技能点

三种基本结构程序设计、常用DOS/BIOS功能调用。

4.实验任务

从键盘输入2个以回车符(CR)结尾的字符串分别存于STRASTRB开始的内存单元中,然后判别STAB中的字符串是否是STRA中字符串的子字符串。如是,显示‘FIND SUB_STRING’,否则显示‘NO  FIND SUB_STRING’

5.实验条件

(1)                                                 PC系列微机一台。

(2)                                                 汇编语言编程环境(MASMTD)

6.实验分析

(1)                                                 程序流程图

STRA串的第一个字符开始搜索与STAB串第一个字符相同的字符,未找到说明STAB串不是STRA串的子字符串;若找到,则用STRA串中从该字符开始且同STRB串等长的子字符串与STRB串进行比较,若两串匹配,则说明STRB串是STRA串的子字符串;否则,从找到的字符的下一字符开始继续寻找与STRB串第一个字符相同的字符,未找到结束;如找到,则重复上述字符串比较过程,直到找到一个与STRB串相同的子字符串,或STRA串搜索完毕。相应的程序流程如图所示。

STRA串长度小于STRB串长度,或经过扫描比较后,STRA串中未扫描的子字符串的长度已小于STRB串长度时,就没有必要再比较了。

若使用串操作指令搜索关键字,找到时,DI指针指向的不是找到的关键字,而是紧随关键字的下一字符(或上一字符),所以字符串匹配前,要调整DI指向正确位置。

(2)                                                 串操作指令

有关串操作指令请参阅实验串操作指令的使用。

两个等长的字符串比较可用带重复前缀的串比较指令(REPZ  CMPSB)实现,也可用计数循环逐个字符比较。若采用子程序结构,可用进位标志CF来传递是否匹配的信息,如CF=0,表示匹配;CF=1,则表示不匹配。

7.思考问题

(1)                                                 若将实验任务改为: 从键盘以十六进制形式输入内存数据区的段基址和段内偏移地址,然后查找从此地址开始的256个字节单元中是否有字母“A”。若找到,显示:FIND “A”;否则,显示:NO FIND “A”。编写程序实现。

(2)                                                 基于MCS-51系列单片机汇编语言设计程序,实现在字符串aBcdfBaejKH中搜索是否存在Ba2个连续的字符,如果存在则向41H单元写01H,将B的位置存入40H单元中;如果不存在,则向41H单元写00H

8.建议学时

课内4学时,外加课外46学时。

2.4 探究型实验项目

2.4.1读写文件

1.实验名称

读写文件

2.实验目的

掌握DOS/BIOS功能调用中读/写文件的方法。

3.实验涉及的知识点和技能点

DOS/BIOS功能调用

4.实验任务

(1)                                                 编写程序,使它相当于DOS操作系统中的TYPE命令的功能。先由屏幕显示提示信息,再读取文件名(含路径),然后在屏幕上显示文件的内容,以^C结束文件的读取。

(2)                                                 编写程序,首先由键盘输入欲建立的文件的路径,然后把从键盘中输入的字符写入指定文件,以^C结束文件的写入。

5.实验条件

(1)       PC系列微机一台。

(2)       汇编语言编程环境。

6.实验分析

(1)                                                 DOS对文件读写操作方法

DOS提供了两种手段。第一种手段是使用FCB进行存取,第二种手段是用文件代号法进行存取。文件代号法支持目录路径,并且对错误采取了更统一的处理方法,是推荐的存取方法。

使用文件代号法,要求文件名(含路径)用ASCII Z串表示。所谓ASCII Z串就是以空字符OOH结尾的一串ASCII字符。使用文件代号法存取出错时,功能调用会在返回时将CF标志置1,同时在AX寄存器中返回出错代码。程序中最好要用JC指令进行错误判定,确认出错后再将出错代码显示出来,以便分析出错原因。

文件创建成功后,要用3DH号子程序打开文件。打开文件要求DS:DX指向ASCII Z串的首地址,AL中送入文件访问方,AL=0,读方式;AL=1,写方式;AL=2,读/写方式。

写文件的子程序号40H,要求DS:DX指向数据缓冲区首单元,BX中放入文件代号,CX中为欲写入的字节数。写文件成功后,要用3E号子程序关闭文件。关闭文件的入口参数BX中存放文件代号。

(2)                                                 读文件程序流程图

(3)                                                 写文件程序流程图

7.思考问题

(1)                                                 如果打开的文件不存在,如何处理?

(2)                                                 读文件、写文件或者关闭文件出错,如何处理?

8.建议学时

课内4学时,外加课外46学时。

2.4.2画图

1.实验名称

画图

2.实验目的

掌握DOS/BIOS功能调用中画图的方法。

3.实验涉及的知识点和技能点

DOS/BIOS功能调用

4.实验任务

编写程序,使PC机在中分辨率(模式4)显示一个等腰三角形。

5.实验条件

(1)       PC系列微机一台。

(2)       汇编语言编程环境。

6.实验分析

(1)       画图方法

对于图形设计,首先应通过BIOS INT 10H调用,将屏幕的工作方式设置为图形方式。 然后选择合适的INT 10H功能调用实现绘画。本题要绘制的三角形,只要用写像素功能画出三条直线,就可画出三角形,关键是要确定好三条线的坐标。

(2)       程序流程图

7.思考问题

(1)       程序结束后如果没有恢复原显示模式会出现什么问题?

(2)       如果想通过左右以及山下移动键控制等腰三角形朝水平以及垂直方向移动,该如何修改程序?

8.建议学时

课内4学时,外加课外46学时。

2.4.3双机串行通信

1.实验名称

双机串行通信

2.实验目的

掌握DOS/BIOS功能调用中串行通信的方法。

3.实验涉及的知识点和技能点

DOS/BIOS功能调用

4.实验任务

编写程序,完成两台计算机之间通过串行通信线相互传送数据。

5.实验条件

(1)       PC系列微机一台。

(2)       汇编语言编程环境。

6.实验分析

(1)       串行通信

在串行通信中,通信接口每次由CPU得到8位数据,然后串行地通过一条线路,每次发送一位。串行通信采用两种方式:同步方式和异步方式。同步传输数据时,一次传送一个字节,而异步传输数据方式是一次传送一个数据块。许多厂商为串行通信生产了专用的芯片,以完成串行通信中对数据的打包、拆包、接收、发送等工作。这种芯片统称为通用异步收发器(简称UART)或同异步收发器(简称USART)。它位于串行适配器板,负责将每个字节转换为10的数据流,并指出每个字节的开始和结束。

(2)       串口编程

IBM PC机的汇编语言中,对串行口的编程方式有两种:I/O指令和中断调用指令,这里介绍中断调用指令的应用。

1)                                                      DOS系统功能调用中的串行通信指令

u       串行口输入

入口参数:AH=03H;出口参数:输入的8位数据。

u       串行口输出

入口参数:AH=04HDL=输出的8位数据;出口参数:无。

功能调用下串行口的通信参数需要由MODE命令设置。MODE命令的格式为:

MODE COMmbpds

这里m表示COM的端口号(1~4)b是比特率(单位时间内传输的二进制位的个数),用波特率高两位数字表示,如11表示110波特,96表示9600波特,19表示19200波特。p是校验位(N为无校验位,O为奇校验,E为偶校验),d表示数据字长(5678位,默认值为7位),S是终止位(1,1.52位)。如果传输率为110波特率,则终止位必须是2位,其他情况下终止位的位数可以是1位。如MODE COM1 24,0,8,1表示为COM1设置的参数是:2400波特率,奇校验,8位字长及1位终止位。

2)                                                      BIOS调用中的串行通信指令

IBM PC及兼容机提供了一种有较强的硬件依赖性但却比较灵活的串行口I/O的方法,即     通过INT 14H调用ROM BIOS串行通信口例行程序。

u       初始化串行通信口(AH=0

入口参数:AL=初始化参数,DX=通信口号;出口参数:AH=通信口状态,AL=调制解调器状态。

初始化参数中8位数据的具体含义如下:

765:设置波特率,如000=110波特;001=150波特;010=300波特;011=600波特;100=1200波特;101=2400波特;110=4800波特;111=9600波特

43:设置校验位,如00=奇校验;11=偶校验;1×=无校验

2:设置终止位,如0=1位;1=2

10:设置字长,如10=7位;11=8

例如以下指令序列是将0号通信口的波特率设置为2400波特,字长为8位,1位终止位,无奇偶校验位。

MOV AH,0

MOV AL,0A3H

MOV DX,0

INT 14H

返回的8位二进制参数中每位的具体含义如下:

   7:超时;位6:发送移位寄存器空;位5:发送保存寄存器空;位4;间断;位3:帧格式错位:位2:奇偶错;位1:超越错;位0:数据准备好

u       向串行通信口写字符(AH=1)

入口参数:AL=所写字符,DX=通信口号;

出口参数:写字符成功,则AH=0AL=字符;写字符失败,则(AH7=1(AH) 0-6=通信口状态。

u       从串行通信口读字符(AH=2

入口参数:DX=通信口号;

出口参数:读字符成功,则(AH7=0AL=字符;读字符失败,则(AH7=1(AH) 0-6=通信口状态。

u       取串行通信口状态(AH=3

入口参数:DX=通信口号。

出口参数:AH=通信口状态,AL=调制解调器状态。

(3)       程序流程图

编程的关键首先是确定串行通信的基本方式。两台计算机可互发数据,即在程序开始时首先检测是否有数据要接收,若没有则检测是否有键按下,若有则开始发送数据,否则重新检测。

7.思考问题

(1)       如果先检测是否发送数据,后检测是否接收数据,会有什么问题?

(2)       如果出现同时发送数据的情况,该如何处理?

8.建议学时

课内4学时,外加课外46学时。

 

2.5典型实验案例

      实验2.5.1  编程实现将键盘输入的十进制数转换为二进制补码

1.实验名称

编程将键盘输入的十进制数转换为二进制补码

2.实验目的

掌握十进制数与二进制数之间的转换方法;

掌握主程序与子程序的接口方法和主—子程序间的参数传递方法。

3.实验涉及的知识点和技能点

80X86汇编级指令系统,源程序结构,汇编语言程序设计的一般过程,基本结构程序设计和子程序设计与调用。

4.实验任务

按主--子程序结构,编程实现以下功能:主程序从键盘输入5位带符号的十进制数(-3276832767),并转换成等值的补码二进制数;然后调用子程序将转换结果以二进制形式从屏幕输出。

5.实验条件

(1)                                                 PC系列微机一台。

(2)                                                 汇编语言编程环境(MASM)

6.实验分析

(1)                                                 十进制数转换成二进制数

X=Xn-1…X1X0n位无符号十进制数,则X转换为二进制数的一般方法为:

                       ……  

    用适合循环的形式表示为:

    ((…((0×10+Xn-1)×10+Xn-2)…)×10+X1)×10+X0             ……  

(2)                                                 二进制数显示

若要用二进制形式显示转换结果,可用移位指令和加法将每位二进制数转换成0/1对应的ASCII码,用DOS2号功能调用显示。图给出了将字变量INTEGER中数以二进制数显示的程序流程。

 

 

 

 

 

 

 

 

 


7.参考答案

(1)                                                 十进制数转换成二进制数

用计数循环结构从高位到低位依次对每位十进制数进行转换处理。算法如下:

                sum=0; i=n-1;

        again:  sum=sum×10;

                sum=sum+X[i];

                i=i-1

                if (i0) goto again

此例要求将带符号十进制数转换成二进制补码数,所以转换开始时要先检测输入的数有无正负号(+-),若有,则剔除+-号,再将无符号的十进制数按上述算法转换成二进制数,若输入的十进制数有符号且符号为‘-’,则还要将结果转换成补码。

(2)                                                 程序清单

假定从键盘输入ASCII码表示的十进制数用DOS0AH号功能调用实现,主程序(带符号十进制数转换成二进制数)与子程序(二进制显示)间采用存储器(变量INTEGER)传递参数,则完成上述功能的程序如下:

    DATA  SEGMENT  USE16

        BUF         DB  6,?               I/O缓冲区(BUF+ASCSTG)

        ASCSTG      DB  10 DUP(?)        ;存放输入的ASCII码数

        INTEGER     DW  0                   ;存放二进制数

        PROMT       DB  ‘INPUT  DECIMAL(5)$’

        ERR         DB  0DH0AH‘ERRORNO DECIMAL$’

    DATA  ENDS

    CODE  SEGMENT  USE16

      ASSUME   CSCODEDSDATA

    START:  MOV     AXDATA

            MOV     DSAX

            MOV     DXOFFSET  PROMT

            MOV     AH09H

            INT     21H                 ;输出提示信息

            MOV     DXOFFSET  BUF ;取缓冲区首址

            MOV     AH0AH

            INT     21H                 ;输入5位十进制数(不含回车符CR)

            LEA     SIASCSTG          SI指向输入的ASCII码十进制数

            XOR     AXAX              ;存放二进制值

            MOV     BL0               ;正负数标志,0为正数

            MOV     BHBUF[1]          取实际输入的十进制数位数

            CMP     BH0

            JZ      EXIT                ;未输入任何数,结束

            MOV     CX10

            MOV     DL[SI]                ;取十进制数的最高位

            CMP     DL‘+’               ;检测是否‘+’

            JNZ     NEXT

            INC     SI                  ;去掉‘+’

            DEC     BH                  ;位数减1

            JMP     CONV

    NEXT  CMP     DL‘-’               ;检测是否‘-’

            JNZ     CONV

            INC     SI                  ;去掉‘-’

            DEC     BH                  ;位数减1

            MOV     BL0FFH            ;置负数标志

    CONV  CMP     BH0               ;处理完?

            JZ      STORE               ;已完,退出转换

            MOV     DL[SI]                ;取1位十进制数

            INC     SI                  SI指向下一位十进制数

            CMP     DL0’

            JB      ERROR               ;非十进制数,转错误处理

            CMP     DL9’

            JA      ERROR

            SUB     DL30H         ;将ASCII码数转换成非压缩BCD

            PUSH    DX                  ;保存当前十进制位的值

            MUL     CX                  ;高位转换结果乘10,存于AX(DX丢弃)

            POP     DX                  ;恢复当前十进制位的值

            ADD     ALDL              加当前十进制位的值

            ADC     AH0

            DEC     BH                  ;位数减1

            JMP     SHORT  CONV

    STORE:  CMP     BL0               ;是否负数?

            JZ      LP

            NEG     AX                  ;是负数,转换成补码

    LP:     MOV     INTEGERAX     ;保存结果

            CALL    DISPLAY         ;调用显示子程序显示转换结果

    EXIT:   MOV     AX4C00H

            INT     21H

    ERROR:  MOV     DXOFFSET ERR

            MOV     AH09H

            INT     21H                 ;输出错误提示

            JMP     EXIT

    DISPLAY   PROC                  16位二进制数显示子程序

            PUSH    AX                  ;保护现场

            PUSH    BX

            PUSH    CX

            MOV     BXINTEGER     取显示二进制数

            MOV     CX10H

    BINDISP:ROL     BX1               ;将最高位送CF

            MOV     DL30H         ;将当前最高位转换成ASCII

            ADC     DL0

            MOV     AH2               ;显示二进制数的当前最高位

            INT     21H

            LOOP    BINDISP

            PUSH    CX                  ;恢复现场

            PUSH    BX

            PUSH    AX

            RET

    DISPLAY   ENDP

    CODE    ENDS

            END     START

8.思考问题

(1)                                                 若将十进制数转换成二进制数也用子程序实现,程序应如何修改?

(2)                                                 若检测到输入数据中有非数字字符时,不仅要求提示输入错误信息,而且要求重新输入数据转换,直到输入正确为止,程序应如何修改?

9.建议学时

课内4学时,外加课外46学时

      实验2.5.2  密码验证程序设计

1.实验名称

密码验证程序设计

2.实验目的

掌握三种基本结构程序的设计方法;

掌握密码验证的程序实现。

3.实验涉及的知识点和技能点

80X86汇编级指令系统,三种基本结构程序设计,常用DOS/BIOS功能调用。

4.实验任务

在内存PASSWORD开始的存储单元存放着NN6)位预先设置好的密码。编写程序从键盘输入N位密码(输入时不显示输入密码,而以‘*’号显示代替,以回车键确认结束),与事先设置的密码进行比较,若相同,显示‘OK’,程序结束;否则显示‘Error’,重新输入密码,连续3次输入错,退出程序。

5.实验条件

(1)                                                 PC系列微机一台。

(2)                                                 汇编语言编程环境(MASM)

6.实验分析

要实现无屏幕回显的密码输入,需使用DOS8号功能调用。每输入一位,保存密码,并用DOS 2号功能调用显示‘*’号,同时记录输入密码位数,直到遇到回车符或已输入完6位密码。然后开始密码验证,验证时,先判断输入密码位数是否相同,若位数不同,则无需比较,表示密码输入错;否则用串比较指令比较判断。相应程序流程如图所示。


7.参考答案

(1)                                                 程序清单

    DATA   SEGMENT

      PASSWORD DB  123456’               ;设置密码

      N         EQU  $ - PASSWORD       ;密码位数

      BUF       DB  6 DUP(?)                ;定义输入缓冲区

      OK        DB  ‘OK$’                 ;定义密码匹配显示信息

      ERROR    DB  ‘Error$’               ;定义密码不匹配显示信息

      DISP       DB  ‘Input Password: $’      ;定义输入提示信息

      CNT       DB  3                       ;设置比较次数

    DATA   ENDS

    CODE   SEGMENT

      ASSUME  CS:CODEDS:DATAES:DATASS:STACK

    START:  MOV   AXDATA              ;建立数据段的可寻址性

            MOV   DSAX

 

            MOV   ESAX

    AGAIN:  LEA    DIDISP                 ;显示提示信息

            MOV   AH9

            INT    21H

            CLD                         ;地址递增

            MOV   BX0                 ;计数器和数组下标清0

    INPUT MOV   AH8                 ;输入密码

            INT    21H                 

            CMP   AL0DH                   ;输入完?

            JZ     NEXT1                   

            MOV   BUF[BX]AL           ;保存输入密码

            MOV   DL‘*’                 ;输出‘*’

            MOV   AH2

            INT    21H

            INC    BX                       ;计数器和数组下标加1

            CMP   BX6                 ;输完6位?

            JZ     NEXT1

            JMP   SHORT  INPUT          ;继续输入

    NEXT1:  CMP   BXN

            JNZ    ERR

            LEA   SIPASSWORD

            LEA    DIBUF

            MOV   CXBX

            REPZ   CMPSB                    ;密码匹配

            JZ      EXIT                    ;正确,转EXIT

    ERR   LEA    DXERROR            ;显示匹配错误信息

            MOV   AH09H

            INT    21H

            DEC    CNT                  ;比较3次?

            JNZ    AGAIN                    ;重新输入密码

            JMP    SHORT  RTUDOS        ;返回DOS

    EXIT:   LEA    DXOK                   ;显示匹配信息

            MOV   AH09H

            INT    21H

    RTUDOSMOV   AH4CH

            INT    21H

    CODE   ENDS

            END   START

8.思考问题

(1)                                                 若规定完成密码输入后,密码匹配过程用子程序实现。修改程序完成实验规定的任务。

9.建议学时

课内4学时,外加课外46学时