汇编程序 - 1 (32位无符号乘法)

Posted andy-lcw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汇编程序 - 1 (32位无符号乘法)相关的知识,希望对你有一定的参考价值。

这个是学校的课程设计《微机原理与接口技术》内容,自己写得有些缺陷,但基本实现了运算功能,暂且记录,方便日后回顾,也供大家参考。

缺陷:

1. 只能固定长度输入(32位对应为00000000 -- FFFFFFFF)

2. 例如输入6(16进制)只能类似输入00000006

3.只考虑了0-F中的0-9输入,也没考虑A-F或者a-f

暂时没空修改,以后有空或许会再写写

 

实验环境:

1.我是在虚拟机上的Windows 7 调试的,TD调试中显示的cpu是80486,但本次实验要求所用8086(16位),这个没影响,因为80486指令集的向前兼容,只要我们写的8086的指令就行。

  说明这个的原因在于,80486已经有新的指令集了,直接可以进行32位运算。

2. ......没了  >==< !

 

设计思路:

输入:

输入时,因为调用INT 21(01H)进行输入,而该功能调用只能每次输入一个字符,且存入AL中的数据为其ASCII值,所以,首先要对输入的值进行转换成真实数据,同时加循环可以完成对固定长度数据的输入。

运算:

运算时,由于在16位寄存器的8086系统中,一次性只能对16位的数据进行运算,故当我们需要对其进行32位运算时,考虑分段进行,每次分段的结果数据(DX:AX)都放在内存相对应地址中(标号为HH、HL、LH、LL)。以32位长度的数据DX:AX两个数据相乘举例,数据分为高位(H)和低位(L),则分段相乘可以分为L-L,L-H,H-L,H-H相乘(L、H代表32位数据的高位数据和低位数据),其中每个相乘的值都放在DX:AX中。在L-L中,L-L->AX由于是乘积的最低位,且MUL指令无溢出情况,故无需考虑进位;在L-L->DX和L-H->AX和H-L->AX之和中,需要考虑向高位进位的情况,可以使用PUSHF将标志寄存器的状态入栈,在高位使用ADC指令即可;L-H->DX和H-L->DX和H-H->AX之和中,需要同时考虑向高位的进位和低位的进位值,处理方法同前;H-H->DX为乘积的最高位,只需考虑低位的进位。

输出:

输出时,要考虑运算后的数据和输出的数据,即运算后的数据为乘积的真值,而输出的数据是字符所对应的ASCII值。同时为了考虑美观性,前置的0考虑将其去除,加判断跳转语句可实现。具体实现是,先判断取出的BX是否为0,为0则代表该数据不用输出,程序跳转到执行下一个地址处理;当取出的数据可能存在开始数据为0100/0A11和非开始数据为0100/0A11的情况。即最开始的0是不用输出的,但是除了最开始的0不输出外,其他的0是真值,需要输出。考虑设计一个标志实现,本设计用SI实现,初始值为0H,当输出一个真值之后,将其值变为01H,之后同时判断SI和要输出的值,当输出值为0且SI为01H时,即该数据为真值,需要输出。

代码:

//mul.asm
DATA        SEGMENT
            BUF1 DB 0DH,0AH,PLEASE INPUT NUM_1(00000000-99999999):,0DH,0AH,$
            BUF2 DB 0DH,0AH,PLEASE INPUT NUM_2(00000000-99999999):,0DH,0AH,$
            BUF3 DB 0DH,0AH,THE RESULT IS:,0DH,0AH,$
            ;做成任意输入的
            NUM1        DW        2 DUP(?)
            NUM2        DW        2 DUP(?)
            HL            DW        2 DUP(?)
            HH            DW        2 DUP(?)
            LH            DW        2 DUP(?)
            LL            DW        2 DUP(?)
            SUM            DW        4 DUP(?)
DATA        ENDS

CODE        SEGMENT
MAIN        PROC    NEAR
            ASSUME    CS:CODE,DS:DATA
START:        
IN_TIPS:
            MOV        BX,DATA
            MOV        DS,BX            
IN_1:
            LEA        DX,BUF1
            MOV        AH,09H
            INT        21H
            LEA        BX,NUM1
            CALL    INPUT
IN_2:
            LEA        DX,BUF2
            MOV        AH,09H
            INT        21H
            LEA        BX,NUM2
            ;ADD        BX,3
            CALL    INPUT
;TAKEMUL
            CALL    TAKEMUL
;OUTPUT                    
            CALL    OUTPUT
;END
            MOV        AH,4CH
            INT        21H
            RET
MAIN        ENDP

INPUT        PROC    NEAR
            MOV        DX,2
INNUM:        
            ;1(5)->Input Number
            MOV        AH,01H
            INT        21H
            SUB        AL,30H    
            MOV        CL,4
            SHL        AL,CL
            MOV        CL,AL
            ;2(6)->Input Number
            MOV        AH,01H
            INT        21H
            SUB        AL,30H
            ADD        CL,AL
            PUSH    CX
            ;3(7)->Input Number
            MOV        AH,01H
            INT        21H
            SUB        AL,30H
            MOV        CL,4
            SHL        AL,CL
            MOV        CH,AL
            ;4(8)->Input Number
            MOV        AH,01H
            INT        21H
            SUB        AL,30H
            ADD        CH,AL
            MOV        AL,CH
            ;SEND To MEMORY
            POP        CX
            MOV        AH,CL
            MOV        [BX],AX
            ADD        BX,2
            DEC        DX
            JNZ        INNUM
            RET
INPUT        ENDP

TAKEMUL        PROC    NEAR
            LEA        SI,NUM1
            LEA        DI,NUM2
H_L:        ;<<16
            MOV        AX,[SI]
            ADD        DI,2
            MUL        WORD PTR[DI]
            LEA        BX,HL
            MOV        [BX],DX
            ADD        BX,2;WORD
            MOV        [BX],AX
            ADD        BX,2
H_H:        ;<<32
            MOV        AX,[SI]
            SUB        DI,2            
            MUL        WORD PTR[DI]
            LEA        BX,HH
            MOV        [BX],DX
            ADD        BX,2
            MOV        [BX],AX
            ADD        BX,2
L_H:        ;<<16
            ADD        SI,2
            MOV        AX,[SI]
            MUL        WORD PTR[DI]
            LEA        BX,LH
            MOV        [BX],DX
            ADD        BX,2
            MOV        [BX],AX
            ADD        BX,2
L_L:        ;<<0
            MOV        AX,[SI]            
            ADD        DI,2
            MUL        WORD PTR[DI]
            LEA        BX,LL
            MOV        [BX],DX
            ADD        BX,2
            MOV        [BX],AX    
            ADD        BX,2            
TAKE:        
            ;L-L:
            ;LL->AX:32位X32位运算数据的最低位
            LEA        DI,LL
            ADD        DI,2
            MOV        AX,[DI]
            LEA        BX,SUM
            MOV        [BX],AX
            ADD        BX,2
            ;LL->DX:LL->DX + LH->AX + HL->AX
            LEA        DI,LL
            MOV        AX,[DI]
            MOV        [BX],AX
            ;ADD        BX,2            
            ;HL+LH
            ;HL->AX+LH->AX
            LEA        DI,HL
            ADD        DI,2
            MOV        AX,[DI]
            LEA        DI,LH
            ADD        DI,2
            ADD        AX,[DI]
            PUSHF
            ADD        AX,[BX];LL->DX            
            MOV        [BX],AX
            ADD        BX,2    
            ;HL->DX+LH->DX (CF)
            LEA        DI,HL
            MOV        AX,[DI]
            LEA        DI,LH
            POPF
            ADC        AX,[DI]
            PUSHF
            MOV        [BX],AX            
            ;HH(CF)
            ;HH->AX
            LEA        DI,HH
            ADD        DI,2
            MOV        AX,[DI]
            POPF
            ADC        AX,[BX];HL->DX+LH->DX
            MOV        [BX],AX
            ADD        BX,2
            ;HH->DX
            LEA        DI,HH
            MOV        AX,[DI]
            ADC        AX,0H
            MOV        [BX],AX
            ADD        BX,2
            RET
TAKEMUL        ENDP

OUTPUT        PROC    NEAR
            LEA        DX,BUF3
            MOV        AH,09H
            INT        21H
            LEA        DI,SUM
            ADD        DI,7
            MOV        CX,8
            MOV        SI,0H;RE_COMPARE
ADJUST:        
            MOV        BL,[DI]
            MOV        BH,BL
            AND        BX,0F00FH
            PUSH    CX
            CMP        BX,0H
            JE        ZERO            
            MOV        CL,4
            SHR        BH,CL
            MOV        DL,BH
            CALL    COMPARE
            MOV        DL,BL
            CALL    COMPARE
ZERO:        
            DEC        DI
            POP        CX
            LOOP    ADJUST
            RET
OUTPUT        ENDP

COMPARE        PROC    NEAR
            CMP        DL,0AH
            JAE        OUT_ENG;JNB
            CMP        DL,00H
            JE        RE_COMPARE
            JA        OUT_NUM
            JMP        COMPARE_END
RE_COMPARE:
            CMP        SI,0H
            JE        COMPARE_END
            JNE        OUT_NUM
OUT_ENG:    
            ADD        DL,37H;ACSII->A-0AH
            MOV        AH,02H
            INT        21H
            MOV        SI,01H
            JMP        COMPARE_END
OUT_NUM:    
            ADD        DL,30H
            MOV        AH,02H
            INT        21H
            MOV        SI,01H
COMPARE_END:
            RET
COMPARE        ENDP

CODE        ENDS
            END        START

由于分析中解释清楚了,加上代码命名相对比较见名知意,所以没注释(极少),之后会上传一个TD工具下的调试Blog,我觉得这个会更有用!!!

 

放两张截图吧 ~__~

说明:输入,输出都为16进制数,为什么是16进制?因为寄存器里面存的的就是16进制啊,我又不傻,直接输出就好,干嘛转换啊。哈哈哈哈哈哈@[email protected],机智!!!

 

验证说明:验证数据通过计算器得出结果。

验证1:12345678H * 12345678H = 14B 66DC 1DF4 D840H

技术图片

验证2:99999999H * 99999999H = 5C28 F5C1 D70A 3D71H

技术图片

验证3:6H * 6 H = 24H

技术图片

 

嗯~ o(* ̄▽ ̄*)o,基本上就这样了!欢迎参考,如果你写了更完整的,欢迎留言提供链接。

 

以上是关于汇编程序 - 1 (32位无符号乘法)的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在没有 bignums 的 JavaScript 中执行快速的 48 位无符号乘法?

如何在 x86(32 位)程序集中将无符号整数转换为浮点数?

如何在 AVX2 中将 32 位无符号整数转换为 16 位无符号整数?

如何从 32 位 R 整数中提取 4 位无符号整数?

Shopee 一面算法题:颠倒给定的 32 位无符号整数

从蓝牙低功耗 GATT 特性中检索大的 32 位无符号整数