高精度乘法程序设计汇编语言版-课程设计

一段尘封已久的代码,当年的课程设计!高精度乘法程序设计汇编语言版
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

转载于:https://my.oschina.net/chwencong/blog/53528

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值