一段尘封已久的代码,当年的课程设计!高精度乘法程序设计汇编语言版
1.1 课程设计题目
高精度乘法程序设计
1.2 课程设计目的
1. 巩固和加深课堂所学知识
2. 将课本上的理论知识和实际应用有机的结合起来,培养同学们分析和解决实际问题的能力
3. 通过对汇编语言程序代码的阅读、修改、设计,理解和掌握复杂的汇编语言应用程序的编程,提高实践编程能力
1.3 程序运行环境及开发工具
本程序主要在装有Windows XP的PC机上利用MASM1的软件来实现。
1.4 程序功能使用说明
运行该程序后,根据提示信息输入形如:–256 * 65536 = 的格式,当键入 ‘ = ’后自行在‘ = ’后输出运算结果,当输入:
1. 输入操作数过程中输入多个符号;
2. 输入‘ = ’前未输入两操作数;
3. 输入‘ * ’前无操作数输入;
4. 输入非法操作数、非法操作符 等
程序会进行出错处理,提示输入错误,要求重新输入。
1.5 关键算法:
1.十进制转化为二进制
ASCII码→二进制数(用于输入)
因键入为整数,故要进行如下转换:
ASCII→BCD→二进制数
1. ASCII→BCD码
将十进制数转换成BCD码要经过以下三步:
1. 取ASCII码的低四位(即十进制数的BCD码表示)。可用指令有(设ASCII码放在AL中):
SUB AL,30H
或 AND AL,0FH
2. 将高字节ASCII码左移四位(其高四位即为BCD码)。可用指令有(设ASCII码放在AH中):
MOV CL,4
SHL AH,CL
或 SAL AH,CL
3.将两字节的BCD码相加
2.BCD→二进制数在本例中采用用以下方法:
将十进制数的BCD码转换为ASCII 码,分为两种情况:
1.对于未组合的BCD码,只要加上 30H即可。可用如下指令(设BCD码放在AL中):
ADD AL,30H
或 OR AL,30H
2.对于组合的BCD码,取其低四位 加上30H,存放在低字节,将原数右移 四位,加上30H存放在高字节。
整体形如: ((((0+千位数)*10+百位数)*10)+十位数)*10+个位数
2.分离64位积
64位积÷1000000000,所得结果为32位商、32位余数
3.二进制转换为十进制
本程序使用了32位指令,涉及32位二进制数的操作,在转换时其步骤:
1. 待转换数除以10
2. 将余数入栈
3. 重复1,2步,直到商等于0
4. 出栈,加上30H并显示
1.5 设计思路:
本程序采用单模块设计,调试方便,程序的易读性好。由于时间及个人水平的问题,在涂老师的指导下,主程序利用了涂老师的程序框架,根据自己的需要做了修改,添加了更为详尽的代码,增加了错误处理,本程序主要包括键盘输入十进制数、十进制转换为二进制、两操作数相乘、积的二进制转换为十进制并输出等,根据自己的理解画了下面的简单的流程图。
实现1.汇编语言实现高精度乘法程序流程图
汇编语言实现高精度乘法程序源代码:
.MODEL SMALL
.386
.STACK
.DATA
FLAG_SIGN DB 0
FLAG_NUM1 DB 0
FLAG_NUM2 DB 0
TEMP DD 0
ARRAY DD 16 DUP(0)
ERR DB 0DH,0AH,'Input error!',0DH,0AH,'$'
STRING DB 0DH,0AH,0DH,0AH,'Please Input(eg. A*B= ) \
("Q" or "q" quit):', 0DH,0AH,'$'
.CODE
.STARTUP
AGAIN:
LEA DX,STRING ;输入提示符
MOV AH,9
INT 21H
MOV EBX,OFFSET ARRAY
MOV FLAG_SIGN,0 ;Init 符号标志 默认0为正
MOV FLAG_NUM1,0 ;操作数输入标志 若无则为0
MOV FLAG_NUM2,0 ;操作数输入标志 若无则为0
L_Input0:
XOR EDX,EDX
XOR ECX,ECX
XOR EAX,EAX
MOV AH,1 ;Input begin
INT 21H
CMP AL,'+'
JZ L_Input1
CMP AL,'-'
JNZ L_Number ;if not '-', maybe unsign
NOT FLAG_SIGN ;符号标志处理
L_Input1:
MOV AH,1
INT 21H
L_Number:
CMP AL,'0'
JB L_Operator
CMP AL,'9'
JA L_Operator
SUB AL,30H ;ascii to bin
ADD EDX,EDX
MOV ECX,EDX
ADD ECX,ECX
ADD ECX,ECX
ADD EDX,ECX
MOV AH,0
ADD EDX,EAX
MOV FLAG_NUM1,1 ;有操作数输入
JMP L_Input1 ;continue input
L_Operator
CMP AL,'*'
JNZ L_Equal
CMP FLAG_NUM1,0 ;' * ' 输入前有无操作数输入
JZ ER
MOV [BX],EDX ;第一操作数送[ BX ]
ADD BX,4
MOV FLAG_NUM1,0 ;为输入第二操作数做准备
MOV FLAG_NUM2,1 ;判断操作数输入标志
JMP L_Input0 ;input other number
L_Equal:
MOV [BX],EDX ;第二操作数存[ BX ] , BX=BX+4
CMP AL,'='
JNZ L_Quit1
MOV BL,FLAG_NUM1 ;判断两操作数的输入
MOV CL,FLAG_NUM2
CMP BL,CL
JNZ ER
CMP FLAG_SIGN,0 ;乘积的符号处理
JZ L_Cal
MOV DL,'-' ;display '-'
MOV AH,2
INT 21H
L_Cal:
MOV CX,0
MOV SI,CX
MOV EAX,ARRAY[SI+4] ;将输入的操作数之一存EAX
MOV EBX,ARRAY[SI] ;将另一操作数存EBX
MUL EBX ;两操作数相乘求积
MOV EBX,1000000000 ;分离乘积中的高32位 , 低32位
DIV EBX ;即分离开 DX , AX
MOV TEMP,EAX ;处理商
CALL BINTOASCII ;将商转换为十进制数并输出
MOV TEMP,EDX ;处理余数
CMP TEMP,0 ;若余数为0 直接输出低位的0
JZ Show_0
CALL BINTOASCII ;将余数转换为十进制数并输出
JMP AGAIN ;返回继续运算
Show_0:
MOV CX,9 ;输出0
Display:
MOV DL,'0'
MOV AH,2
INT 21H
DEC CX
CMP CX,0
JNZ Display
JMP AGAIN ;返回继续运算
L_Quit1:
CMP AL,'Q' ;'Q ' or 'q' 则退出
JNZ L_Quit2
JMP L_Quit
L_Quit2:
CMP AL,'q'
JNZ ER
JMP L_Quit
ER:
MOV DX,OFFSET ERR ;错误处理
MOV AH,9
INT 21H
JMP AGAIN
L_Quit:
.EXIT 0
;子程序名: BINTOASCII
;子程序功能: 将无符号双字变量TEMP中的二进制数抓转换位相应的十进制 \ 的ASCII码并输出
;入口参数: 双字变量TEMP
;出口参数: 无
;所使用寄存器:EBX , EAX , EDX
BINTOASCII PROC
PUSH EAX ;保护现场
PUSH EBX
PUSH ECX
PUSH EDX
MOV EAX,TEMP ;待处理数存EAX
MOV EBX,10
PUSH BX ;压入10作为结束标志
B3:
CMP EAX,0 ;EAX=0 ( 数据为0 ) ,则退出
JZ B4
SUB EDX,EDX ;扩展 EDX 为 0
DIV EBX ;EDX:EAX/EBX ( 10 )
ADD DL,30H ;余数转换为ASCII码
PUSH DX ;并将其入栈
JMP B3
B4:
POP DX ;将各位数出栈
CMP DL,10 ;是结束标志( 10 ) ,则退出
JE B5
MOV AH,2 ;显示各数
INT 21H
JMP B4
B5:
POP EDX ;恢复现场
POP ECX
POP EBX
POP EAX
RET
BINTOASCII ENDP
END
运行结果截图:
课程设计心得:
经过一个星期的上机实践学习,使我对汇编语言有了更进一步的认识和了解,要想学好它要重在实践,要通过不断的上机操作才能更好地学习它,通过实践,我也发现我的好多不足之处,首先是自己在指法上还不行,经常按错字母,通过学习也有所改进;再有对汇编语言的一些指令不太了解,还有对函数调用的正确使用不够熟悉,通过实践,使我在这几个方面的认识有所提高。
通过实践的学习,我认到学好计算机要重视实践操作,不仅仅是学习汇编语言,还是其它的语言,以及其它的计算机方面的知识都要重在实践,所以后在学习过程中,我会更加注视实践操作,使自己便好地学好计算机。
参考文献:
[1]沈美明,温冬婵.IBM-PC汇编语言程序设计[M].北京:清华大学出版社,1991.
[2]赵树升,杨建军.DOS/Windows汇编语言程序设计教程. 北京:清华大学出版社,2005.6
[3]钱晓捷. 汇编语言程序设计(第二版). 北京:电子工业出版社,2003.6
来源:oschina
链接:https://my.oschina.net/u/135629/blog/53528