一段尘封已久的代码,当年的课程设计!高精度乘法程序设计汇编语言版
1.1 课程设计题目算法
高精度乘法程序设计编程
1.2 课程设计目的框架
1. 巩固和加深课堂所学知识函数
2. 将课本上的理论知识和实际应用有机的结合起来,培养同窗们分析和解决实际问题的能力工具
3. 经过对汇编语言程序代码的阅读、修改、设计,理解和掌握复杂的汇编语言应用程序的编程,提升实践编程能力学习
1.3 程序运行环境及开发工具开发工具
本程序主要在装有Windows XP的PC机上利用MASM1的软件来实现。ui
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