汇编语言课程设计.docx
- 文档编号:26443532
- 上传时间:2023-06-19
- 格式:DOCX
- 页数:21
- 大小:72.33KB
汇编语言课程设计.docx
《汇编语言课程设计.docx》由会员分享,可在线阅读,更多相关《汇编语言课程设计.docx(21页珍藏版)》请在冰豆网上搜索。
汇编语言课程设计
《汇编语言》课程设计
任
务
书
一、题目
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)每个程序应作较多测试,以证明程序的正确性
实验一:
源代码:
DATASEGMENT
SIGDB00H;用来记录要进行的运算
NUM1DW0;用来记录输入的第一个数
NUM2DW0;用来记录输入的第二个数
XDB10;当输入的下一个数字时,大小为前一个数需要乘10
DATAENDS;再加上当前的数
CODESEGMENT
MAINPROCFAR
ASSUMECS:
CODE,DS:
DATA
START:
MAINT1:
MOVAH,1;输入要运算的算式
INT21H
MAINT3:
CMPAL,30H;和0作比较
JLL1;小于0时转去L1
CMPAL,3DH
JZMAINT2;当输入”=”时转去MAINT2进行计算结果
CALLBIN;调用子程序BIN,计算数值真实大小
CMPDX,1
JNZL5
NEGBX;当DX为1使需对BX进行取反
MOVDX,0;恢复DX
L5:
CMPCX,1
JZL3
MOVNUM2,BX;CX不等于1时记录当前输入的第二个数
JMPMAINT3
L3:
MOVNUM1,BX;记录当前输入的第一个数
JMPMAINT3
L1:
CMPAL,2EH
JZquit;当输入的字符为”.”时转去quit,即程序运行结束
CMPCX,1
JNZL2
MOVSIG,AL;当CX不等于1时,即为当前要进行的运算
MOVCX,2
JMPMAINT1;返回MINT1继续输入算式
L2:
CMPAL,2DH
JNZMAINT1
MOVDX,1
JMPMAINT1
quit:
MOVAH,4CH;程序运行结束
INT21H
MAINT2:
CMPSIG,'+';SIG为”+”时进行加法操作
JNZS1
MOVAX,NUM1
MOVBX,NUM2
ADDAX,BX
JMPMAINT4
S1:
CMPSIG,'-';SIG为”-”时进行减法操作
JNZS2
MOVAX,NUM1
SUBAX,NUM2
JMPMAINT4
S2:
CMPSIG,'*';SIG为”*”时进行乘法操作
JNZS3
MOVAX,NUM1
MOVDX,0
IMULNUM2
JMPMAINT4
S3:
MOVAX,NUM1;否则进行除法运算
MOVBX,NUM2
IDIVBL
CBW
MAINT4:
MOVBP,SP;当数为负数时进行取反操作
TESTAX,8000H
JZOUT2
MOVBX,AX
MOVDL,'-'
MOVAH,2
INT21H
MOVAX,BX
NEGAX;取AX的反
OUT2:
DIVX;不断乘以10
MOVBL,AH
MOVBH,0
PUSHBX
MOVAH,0
CMPAL,0
JNZOUT2
OUT3:
POPDX;输出所求的结果
ADDDL,30H;因为显示的是ascall码,所以需加上30H
MOVAH,2
INT21H
CMPBP,SP;当bp和sp指向同一位置时输出结束
JNZOUT3
MOVDL,0AH
MOVAH,2
INT21H
MOVDL,0DH
MOVAH,2
INT21H
JMPSTART;返回START进行下一轮计算
MAINENDP
BINPROCNEAR;子程序BIN用来转换输入的数字大小,即计算数值
;的真实大小
PUSHDX
MOVBX,0
INCCX
SUBAL,30H
CBW
XCHGAX,BX
MOVDX,10
MULDX
XCHGAX,BX
ADDBX,AX
BINT1:
MOVAH,1
INT21H
CMPAL,30H;判断输入的字符是否为数值
JLEXIT
CMPAL,3DH
JZEXIT;当输入的字符不为字符时退出子程序BIN
SUBAL,30H
CBW
XCHGAX,BX
MOVDX,10;同过乘10相加得到真实数值
MULDX
XCHGAX,BX
ADDBX,AX
JMPBINT1
EXIT:
POPDX
RET
BINENDP
CODEENDS
ENDSTART
运行结果:
实验二:
源代码:
DATASEGMENT
;DICTIONARY字典字符串,首两个字节为16位无符号二进制数,说明字符串长度。
DICTIONARYDB00,19H,"applebirdgoodhappy"
DB100HDUP(20H);空的缓冲区。
MSG_INTRODB"InputtheWordtoSearch:
","$"
MSG_NOTFOUNDDB"NotFound,NowInsertit.",0AH,0DH,"$"
MSG_NEWDICTDB0AH,0DH,"NewDictionary:
","$"
MSG_FOUNDDB0AH,0DH,"FoundWordinDictionary:
","$"
MSG_POSITIONDB0AH,0DH,"Position:
","$"
MSG_DICTLENGTHDB0AH,0DH,"NewDictionaryLength:
","$"
MSG_NEWLINEDB0AH,0DH,"$"
BUFFERDB10HDUP(20H);BUFFER用于保存需要查询的单词。
WORD_LENGTHDB0H
CHAR_SPACEEQU20H;默认的单词间隔为空格。
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
start:
MOVAX,DATA
MOVDS,AX
LEABX,BUFFER;把buffer有效地址送BX
MOVDX,OFFSETMSG_INTRO;把偏移地址送DX通用寄存器
MOVAH,09H;调用9号中断,输出MSG_INTRO
INT21H
GET_WORD:
;获取用户输入的需要查找的单词字符串。
MOVAH,01H
INT21H
CMPAL,0DH;输入以回车结束。
JEINPUT_FINISH;如果是回车,跳转输入结束
MOV[BX],AL
INCBX;BX加1,下一步修改字符长度
INCWORD_LENGTH
JMPGET_WORD
INPUT_FINISH:
MOVDX,OFFSETMSG_NEWLINE;把偏移地址送DX通用寄存器
MOVAH,09H
INT21H
SUBBX,WORDPTRWORD_LENGTH
MOVCX,00H
MOVSI,02H
SEARCH:
MOVDL,[BX];把输入的字符放到DL
CMPDL,DICTIONARY[SI];比较[BX]和DICTIONARY[SI]内容是否匹配。
JEMATCH;结果匹配。
JNLUNMATCH_NEXT;需要查找下一个单词。
JLUNMATCH_INSERT;找到了输入单词的插入位置,将要插入这个单词。
MATCH:
MOVDL,DICTIONARY[SI+1]
CMPDL,CHAR_SPACE;如果DICTIONARY下一位字符为空格,查找成功。
JNENOFOUND
JMPFOUND
NOFOUND:
INCBX;匹配了1位字符,继续比较下一位。
INCSI
INCCX;匹配计数器增加一位。
JMPSEARCH
UNMATCH_NEXT:
;如果当前字典中的单词不匹配,BUFFER回到首地址,DICTIONARY[SI]到下一个单词。
SUBBX,CX;将BX恢复初始位置。
MOVCX,0H;匹配计数器CX清零。
;找到下一个单词的起始位置。
TO_NEW_WORD:
MOVDH,DICTIONARY[0]
MOVDL,DICTIONARY[1]
INCDX
CMPDX,SI
JEINSERT_LAST
MOVDL,DICTIONARY[SI]
INCSI
CMPDL,CHAR_SPACE
JNETO_NEW_WORD
JMPSEARCH;新的匹配查找。
;已经到了字典字符串的最后。
UNMATCH_INSERT:
;字典中的下一个单词比输入查询的单词"小",将在这个单词前面插入新单词。
;将DICTIONARY[SI-CX]后面的单词向后移动WORD_LENGTH字节,为新的单词空出。
;最后修改串的长度。
MOVAX,SI
SUBAX,CX
SUBBX,CX
MOVDH,DICTIONARY[0];获得串长度。
MOVDL,DICTIONARY[1]
MOVSI,DX;从最后一个字符开始,向后移动字典字符串。
RIGHT_MOVE:
DECSI
MOVDL,DICTIONARY[SI]
ADDSI,WORDPTRWORD_LENGTH
INCSI
MOVDICTIONARY[SI],DL
SUBSI,WORDPTRWORD_LENGTH
DECSI
CMPSI,AX
JNERIGHT_MOVE
MOVSI,AX
MOVCX,WORDPTRWORD_LENGTH
;在新的位置插入新单词。
INSERT:
MOVDL,[BX]
MOVDICTIONARY[SI],DL
INCBX
INCSI
LOOPINSERT
;在新添加的单词后面补充一个空格。
MOVDICTIONARY[SI],CHAR_SPACE
;修改字符串长度。
MOVDH,DICTIONARY[0]
MOVDL,DICTIONARY[1]
ADDDX,WORDPTRWORD_LENGTH
MOVDICTIONARY[0],DH
MOVDICTIONARY[1],DL
SHOW_NEWINSERT:
;显示插入新单词的位置和新的字符串。
MOVDX,OFFSETMSG_NEWLINE
MOVAH,09H
INT21H
MOVDX,OFFSETMSG_NOTFOUND
MOVAH,09H
INT21H
JMPSHOW_DICT
INSERT_LAST:
;在字典字符串的最后面插入新单词。
SUBBX,CX
DECSI
MOVCX,WORDPTRWORD_LENGTH
INSERTWORD:
MOVDL,[BX]
MOVDICTIONARY[SI],DL
INCBX
INCSI
LOOPINSERTWORD
;在新添加的单词后面补充一个空格。
MOVDICTIONARY[SI],CHAR_SPACE
;修改字符串长度。
MOVDH,DICTIONARY[0]
MOVDL,DICTIONARY[1]
ADDDX,WORDPTRWORD_LENGTH
MOVDICTIONARY[0],DH
MOVDICTIONARY[1],DL
JMPSHOW_NEWINSERT
FOUND:
;如果新的单词和字典中的某一个单词前面部分相同,
;新单词为:
and,字典里的单词为an,则将新单词插入到an的后面。
MOVDX,WORDPTRWORD_LENGTH
DECDX
CMPCX,DX
JEMATCH_NEXT
JMPUNMATCH_NEXT
;显示找到的该单词在字典字符串中的位置。
MATCH_NEXT:
MOVDX,OFFSETMSG_POSITION
MOVAH,09H
INT21H
SUBSI,WORDPTRWORD_LENGTH
CALLBINIDEC
MOVDX,OFFSETMSG_FOUND
MOVAH,09H
INT21H
MOVCX,WORDPTRWORD_LENGTH;CX用于循环输出匹配单元的信息计数器。
SUBBX,WORDPTRWORD_LENGTH;循环7次,输出数据表中的信息。
SHOW:
INCBX
MOVDL,[BX]
MOVAH,02H
INT21H
LOOPSHOW
JMPQUIT
SHOW_DICT:
;显示新插入的单词在字典字符串中的位置。
MOVDX,OFFSETMSG_POSITION
MOVAH,09H
INT21H
SUBSI,WORDPTRWORD_LENGTH
DECSI
CALLBINIDEC
;显示新的字典字符串长度。
MOVDX,OFFSETMSG_DICTLENGTH
MOVAH,09H
INT21H
MOVDH,DICTIONARY[0]
MOVDL,DICTIONARY[1]
SUBDX,02H
MOVSI,DX
CALLBINIDEC
;循环输出,显示新的字典字符串。
MOVDX,OFFSETMSG_NEWDICT
MOVAH,09H
INT21H
MOVCH,DICTIONARY[0]
MOVCL,DICTIONARY[1]
MOVSI,02H
RT:
MOVDL,DICTIONARY[SI]
INCSI
MOVAH,02H
INT21H
LOOPRT
QUIT:
MOVAH,4CH;ReturntoDOS.
INT21H
;BINIDEC子程序,将SI寄存器中的数据转化为十进制数字输出在屏幕上。
BINIDECPROCNEAR
MOVCX,100D
CALLDEC_DIV
MOVCX,10D
CALLDEC_DIV
MOVCX,1D
CALLDEC_DIV
RET
DEC_DIVPROCNEAR
MOVAX,SI
MOVDX,0
DIVCX
MOVSI,DX
MOVDL,AL
ADDDL,30H
MOVAH,2H
INT21H
RET
DEC_DIVENDP
BINIDECENDP
CODEENDS
ENDSTART
运行结果:
实验三:
源代码:
STACKSEGMENTPARA'STACK'
DB64DUP('STACK...')
STACKENDS
DSEGSEGMENTPARA'DATA'
TABLEDW440;对应6音调
DW494;对应7音调
DW524;对应1音调
DW588;对应2音调
DW660;对应3音调
DW698;对应4音调
DW784;对应5音调
DW880;对应6音调
DW988;对应7音调
DW1048;对应i音调
DSEGENDS
CSEGSEGMENTPARA'CODE'
ASSUMECS:
CSEG,DS:
DSEG,SS:
STACK
MAINPROCFAR
MOVAX,DSEG
MOVDS,AX
NEW_NOTE:
MOVAH,0;读出键盘输入
INT16H
CMPAL,'.';当输入为“,”时程序运行结束
JEEXIT
MOVBX,OFFSETTABLE;得到TABLE的首地址
CMPAL,'1';判断是否为1~8
JBDOWN
CMPAL,'8'
JADOWN
ANDAX,0FH;ax的高4位清零
SHLAX,1;ax乘以2
SUBAX,2;转换ASCLL码
MOVSI,AX
ADDSI,4
NEXT:
MOVDI,[BX][SI]
MOVBX,10;等待0.1秒
CALLSOUNDF;执行子程序SOUNDF
JMPNEW_NOTE
DOWN:
CMPAL,'0'
JEDOWN1
CMPAL,'9'
JEDOWN2
JMPNEW_NOTE;当输入的数不为0~9时重新输入
DOWN1:
MOVSI,2
JMPNEXT
DOWN2:
MOVSI,0
JMPNEXT
EXIT:
MOVAX,4C00H;退出程序
INT21H
MAINENDP
WAITFPROCFAR
PUSHAX
WAITF1:
INAL,61H
ANDAL,10H
CMPAL,AH
JEWAITF1
MOVAH,AL
LOOPWAITF1
POPAX
RET
WAITFENDP
SOUNDFPROCNEAR;发生子程序SOUNDF
PUSHAX;保存寄存器
PUSHBX
PUSHCX
PUSHDX
PUSHDI
MOVAL,0B6H;计时器模式
OUT43H,AL
MOVDX,12H;计时器因子
MOVAX,348CH;1193100Hz
DIVDI;平率的值
OUT42H,AL;写计时器2数的低字
MOVAL,AH
OUT42H,AL;写计时器2数的高字
INAL,61H
MOVAH,AL
ORAL,3
OUT61H,AL
MOVBX,100
WAIT1:
MOVCX,663
CALLWAITF
DELAY:
LOOPDELAY
DECBX
JNZWAIT1
MOVAL,AH
OUT61H,AL
POPDI;恢复寄存器
POPDX
POPCX
POPBX
POPAX
RET
SOUNDFENDP
CSEGENDS
ENDMAIN
四、实验心得体会
1.除了第三个实验可以直接参考书本外,前两个实验题目比较难,尤其是第一个程序执行时需要不断的转移,很容易弄错而且检查起来也比较麻烦。
后来在和同学讨论后参考有关资料才基本完成本次实验。
2.本次课程设计的基本达到了设计目的。
程序经编译、链接,没有发现错误,可以得到正确结果。
3.
3.本次实验过程中通过自己查阅资料,增加了课外知识。
4.通过本次课程设计提高分析问题、解决问题的能力以及实际动手能力,进一步加深对汇编语言程序设计基本理论的理解,也增加了自己汇编程序设计的能力。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 汇编语言 课程设计