汇编语言课程设计

更新时间:2023-11-10 17:04:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

《 汇编语言》课程设计

任 务 书

一、题目

1.简单的计算器 2.字典 3.“Pc”钢琴

二、目的:

本次课程设计的目的是提高学生分析问题、解决问题的能力以及实际动手能力,进一步加深学生对汇编语言程序设计基本理论的理解,使学生熟练掌握汇编语言程序上机调试的方法技巧、结构化程序设计技术及高级汇编语言技术,能编写较复杂的应用程序,为学习后继课程打下扎实的基础。

三、已知技术参数和设计要求:

1.编写一个有符号多位十进制数的四则运算计算器程序,所输入的算式如下例所示: -278+32= -132――12= 11*-32= -1234/-18=

要求程序能接收键入的算式,在接收到‘=’号时,计算并以有符号十进制数的形式显示结果,然后允许用户继续键入算式。如果键入算式后再键入‘.’,则显示结果并结束整个程序。(‘/’为整除)

2.已知一个由英语单词组成的字符串已按字典序排好,每个单词以空格符为结束,该串的首二字节为16位无符号二进制数,用以说明串的长度。试编程能从键盘上输入单词(以空格字符为结束),若字符串中没有该单词,则将该单词插入该串适当的位置,使其仍保持字典序,并修改串长度,显示单词在串中位置及串长度;若字符串中有该单词,则显示字符串中所有包含该单词的单词,及其在字符串中的位置。

3.编写程序,程序运行时使PC机成为一架可弹奏的“钢琴”。当按下数字键0~9时,发出6,7,1,2,3,4,5,6,7,i,十个音调,按‘.’则退出“钢琴”状态。

总体要求

1)程序结构清晰,相对独立的功能应尽量用子程序实现 2)有较多提示信息,以方便用户使用 3)能检测用户输入的错误,并作相应处理 4)每个程序应作较多测试,以证明程序的正确性

2

实验一: 源代码: DATA SEGMENT SIG DB 00H ;用来记录要进行的运算 NUM1 DW 0 ;用来记录输入的第一个数 NUM2 DW 0

;用来记录输入的第二个数

X DB 10 ;当输入的下一个数字时,大小为前一个数需要乘10

DATA ENDS

;再加上当前的数

CODE SEGMENT MAIN PROC FAR ASSUME CS:CODE,DS:DATA START:

MAINT1: MOV AH,1 ;输入要运算的算式

INT 21H

MAINT3:

CMP AL,30H

;和0作比较 JL L1

;小于0时转去L1 CMP AL,3DH

JZ MAINT2 ;当输入”=”时转去MAINT2进行计算结果 CALL BIN

;调用子程序BIN,计算数值真实大小 CMP DX,1 JNZ L5 NEG BX

;当DX为1使需对BX进行取反 MOV DX,0

;恢复DX

L5: CMP CX,1

JZ L3 MOV NUM2,BX

; CX不等于1时记录当前输入的第二个数

JMP MAINT3

L3: MOV NUM1,BX

;记录当前输入的第一个数

JMP MAINT3 L1: CMP AL,2EH

JZ quit

;当输入的字符为”.”时转去quit,即程序运行结束

CMP CX,1 JNZ L2 MOV SIG,AL ;当CX不等于1时,即为当前要进行的运算

MOV CX,2

3

JMP MAINT1 ;返回MINT1继续输入算式

L2: CMP AL,2DH

JNZ MAINT1 MOV DX,1 JMP MAINT1

quit: MOV AH,4CH

INT 21H

MAINT2:

CMP SIG,'+'

JNZ S1 MOV AX,NUM1 MOV BX,NUM2 ADD AX,BX JMP MAINT4

S1: CMP SIG,'-'

JNZ S2 MOV AX,NUM1 SUB AX,NUM2 JMP MAINT4

S2: CMP SIG,'*'

JNZ S3 MOV AX,NUM1 MOV DX,0 IMUL NUM2 JMP MAINT4

S3: MOV AX,NUM1

MOV BX,NUM2 IDIV BL CBW

MAINT4:

MOV BP,SP TEST AX,8000H JZ OUT2 MOV BX,AX

MOV DL,'-'

;程序运行结束

;SIG为”+”时进行加法操作

;SIG为”-”时进行减法操作

;SIG为”*”时进行乘法操作

;否则进行除法运算

;当数为负数时进行取反操作4

MOV AH,2 INT 21H MOV AX,BX NEG AX

OUT2: DIV X

MOV BL,AH MOV BH,0 PUSH BX MOV AH,0 CMP AL,0 JNZ OUT2

OUT3: POP DX

ADD DL,30H

MOV AH,2 INT 21H CMP BP,SP

JNZ OUT3 MOV DL,0AH MOV AH,2

INT 21H MOV DL,0DH MOV AH,2 INT 21H JMP START

MAIN ENDP

BIN PROC NEAR ; PUSH DX MOV BX,0 INC CX SUB AL,30H CBW XCHG AX,BX

MOV DX,10

;取AX的反

;不断乘以10

;输出所求的结果

;因为显示的是ascall码,所以需加上30H

;当bp和sp指向同一位置时输出结束

;返回START进行下一轮计算 子程序BIN用来转换输入的数字大小,即计算数值;的真实大小

5

MUL DX XCHG AX,BX ADD BX,AX INT 21H BINT1: MOV AH,1

CMP AL,30H

JL EXIT CMP AL,3DH JZ EXIT

SUB AL,30H

CBW XCHG AX,BX MOV DX,10

MUL DX XCHG AX,BX ADD BX,AX JMP BINT1 EXIT: POP DX

RET

BIN ENDP CODE ENDS END START 运行结果:

;判断输入的字符是否为数值

;当输入的字符不为字符时退出子程序BIN

;同过乘10相加得到真实数值

6

实验二: 源代码:

DATA SEGMENT

; DICTIONARY 字典字符串,首两个字节为 16 位无符号二进制数,说明字符串长度。

DICTIONARY DB 00,19H,\

DB 100H DUP(20H) ; 空的缓冲区。 MSG_INTRO DB \ MSG_NOTFOUND DB \ MSG_NEWDICT DB 0AH,0DH,\

MSG_FOUND DB 0AH,0DH,\ MSG_POSITION DB 0AH,0DH,\

MSG_DICTLENGTH DB 0AH,0DH,\ MSG_NEWLINE DB 0AH,0DH,\ BUFFER DB 10H DUP(20H) ; BUFFER 用于保存需要查询的单词。 WORD_LENGTH DB 0H CHAR_SPACE EQU 20H ;默认的单词间隔为空格。 DATA ENDS CODE SEGMENT

ASSUME CS:CODE, DS:DATA start:

MOV AX,DATA MOV DS,AX LEA BX,BUFFER;把buffer有效地址送BX

MOV DX,OFFSET MSG_INTRO ;把偏移地址送DX通用寄存器 MOV AH,09H ;调用9号中断,输出MSG_INTRO

7

INT 21H GET_WORD:

; 获取用户输入的需要查找的单词字符串。 MOV AH,01H INT 21H CMP AL,0DH ; 输入以回车结束。

JE INPUT_FINISH ;如果是回车,跳转输入结束 MOV [BX],AL INC BX ;BX加1,下一步修改字符长度 INC WORD_LENGTH JMP GET_WORD INPUT_FINISH: MOV DX,OFFSET MSG_NEWLINE ;把偏移地址送DX通用寄存器 MOV AH,09H INT 21H SUB BX,WORD PTR WORD_LENGTH MOV CX,00H

MOV SI,02H SEARCH: MOV DL,[BX] ;把输入的字符放到DL CMP DL,DICTIONARY[SI] ; 比较[BX]和DICTIONARY[SI]内容是否匹配。 JE MATCH ; 结果匹配。 JNL UNMATCH_NEXT ; 需要查找下一个单词。

JL UNMATCH_INSERT ; 找到了输入单词的插入位置,将要插入这个单词。 MATCH: MOV DL,DICTIONARY[SI+1] CMP DL,CHAR_SPACE ; 如果DICTIONARY下一位字符为空格,查找成功。 JNE NOFOUND JMP FOUND NOFOUND: INC BX ; 匹配了 1 位字符,继续比较下一位。 INC SI INC CX ; 匹配计数器增加一位。 JMP SEARCH UNMATCH_NEXT:

; 如果当前字典中的单词不匹配,BUFFER 回到首地址,DICTIONARY[SI]到下一个单词。 SUB BX,CX ; 将 BX 恢复初始位置。 MOV CX,0H ; 匹配计数器 CX 清零。 ; 找到下一个单词的起始位置。 TO_NEW_WORD: MOV DH,DICTIONARY[0] MOV DL,DICTIONARY[1] INC DX CMP DX,SI

8

JE INSERT_LAST MOV DL,DICTIONARY[SI] INC SI CMP DL,CHAR_SPACE JNE TO_NEW_WORD JMP SEARCH ; 新的匹配查找。

; 已经到了字典字符串的最后。 UNMATCH_INSERT:

; 字典中的下一个单词比输入查询的单词\小\,将在这个单词前面插入新单词。 ; 将DICTIONARY[SI-CX]后面的单词向后移动WORD_LENGTH字节,为新的单词空出。 ; 最后修改串的长度。 MOV AX,SI SUB AX,CX SUB BX,CX MOV DH,DICTIONARY[0] ; 获得串长度。 MOV DL,DICTIONARY[1] MOV SI,DX ; 从最后一个字符开始,向后移动字典字符串。 RIGHT_MOVE: DEC SI MOV DL,DICTIONARY[SI] ADD SI,WORD PTR WORD_LENGTH INC SI MOV DICTIONARY[SI],DL SUB SI,WORD PTR WORD_LENGTH DEC SI CMP SI,AX JNE RIGHT_MOVE MOV SI,AX MOV CX,WORD PTR WORD_LENGTH ; 在新的位置插入新单词。 INSERT: MOV DL,[BX] MOV DICTIONARY[SI],DL INC BX INC SI

LOOP INSERT

; 在新添加的单词后面补充一个空格。 MOV DICTIONARY[SI],CHAR_SPACE ; 修改字符串长度。 MOV DH,DICTIONARY[0] MOV DL,DICTIONARY[1] ADD DX,WORD PTR WORD_LENGTH MOV DICTIONARY[0],DH MOV DICTIONARY[1],DL

9

SHOW_NEWINSERT:

; 显示插入新单词的位置和新的字符串。 MOV DX,OFFSET MSG_NEWLINE MOV AH,09H INT 21H MOV DX,OFFSET MSG_NOTFOUND MOV AH,09H INT 21H JMP SHOW_DICT INSERT_LAST:

; 在字典字符串的最后面插入新单词。 SUB BX,CX DEC SI MOV CX,WORD PTR WORD_LENGTH INSERTWORD: MOV DL,[BX] MOV DICTIONARY[SI],DL INC BX INC SI

LOOP INSERTWORD

; 在新添加的单词后面补充一个空格。 MOV DICTIONARY[SI],CHAR_SPACE ; 修改字符串长度。 MOV DH,DICTIONARY[0] MOV DL,DICTIONARY[1] ADD DX,WORD PTR WORD_LENGTH MOV DICTIONARY[0],DH MOV DICTIONARY[1],DL JMP SHOW_NEWINSERT FOUND:

; 如果新的单词和字典中的某一个单词前面部分相同,

; 新单词为: and ,字典里的单词为 an,则将新单词插入到 an 的后面。 MOV DX,WORD PTR WORD_LENGTH DEC DX CMP CX,DX

JE MATCH_NEXT

JMP UNMATCH_NEXT

; 显示找到的该单词在字典字符串中的位置。 MATCH_NEXT: MOV DX,OFFSET MSG_POSITION MOV AH,09H INT 21H SUB SI,WORD PTR WORD_LENGTH CALL BINIDEC

10

本文来源:https://www.bwwdw.com/article/mz0v.html

Top