汇编程序 - 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,基本上就这样了!欢迎参考,如果你写了更完整的,欢迎留言提供链接。

原文地址:https://www.cnblogs.com/Andy-Lcw/p/11178855.html

时间: 2024-10-11 08:19:54

汇编程序 - 1 (32位无符号乘法)的相关文章

leetcode——190 Reverse Bits(32位无符号二进制数的翻转)

Reverse bits of a given 32 bits unsigned integer. For example, given input 43261596 (represented in binary as 00000010100101000001111010011100), return 964176192 (represented in binary as 00111001011110000010100101000000). Follow up: If this function

8位无符号和8位有符号转化为更高字节类型的问题

main() { unsigned char uch=0xff; //数值为255 char ch=0xff; //数值为-1 int i=0; i=i+uch; printf("%x\n",i); i=0; i=i+ch; printf("%x\n",i); } 运行结果为: ff ffffffff 解释:C语言将低字节类型转化高字节类型时,转化会保证转化前后所对应的数值不变,而不是保证转化后的低字节的各个比特位与之前相同.高字节为0. 为什么两者不能同时保证,那

汇编总结:无符号除法,有符号除法,取余,无符号乘法,有符号乘法

本文分为3个模块. 示例---该指令的示例 解释---为指令不好理解的地方 练习---为了更熟悉该指令 1.1 有符号除法指令及取余example: 在c语言里要完成 8 / 2的汇编指令如下: 在c语言里要完成 8 % 2的汇编指令如下: 4个字节的除法及取余运算示例如下: .section .text .global _start _start:     movl $8, %eax   #被除数是%edx:%eax 是这两个寄存器拼起来的%eax存放低位%edx存储高位     movl %

uint8是8位无符号整型,uint16是16位无符号整型。

整型有无符号(unsigned)和有符号(signed)两种类型,在默认情况下声明的整型变量都是有符号的类型(char有点特别),如果需声明无符号类型的话就需要在类型前加上unsigned.在一些不可能取值为负数的时候,可以定义为unsigned,在一些底层的嵌入式编程的数据一般都是无符号. 向左转|向右转 扩展资料: 负数时的有符号整型和无符号整型的转换 当执行一个运算时(如这里的a>b),如果它的一个运算数是有符号的而另一个数是无符号的,那么C语言会隐式地将有符号 参数强制类型为无符号数,并

C#Winform基础 十进制整数转换为32位有符号二进制数

镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ 1 UI 2 code 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using S

编译器是如何实现32位整型的常量整数除法优化的?[C/C++]

引子 在我之前的一篇文章[ ThoughtWorks代码挑战——FizzBuzzWhizz游戏 通用高速版(C/C++ & C#) ]里曾经提到过编译器在处理被除数为常数的除法时,是有优化的,今天整理出来,一来可以了解是怎么实现的,二来如果你哪天要写编译器,这个理论可以用得上.此外,也算我的一个笔记. 实例 我们先来看一看编译器优化的实例.我们所说的被除数为常数的整数除法(针对无符号整型, 有符号整型我们后面再讨论),指的是,对于unsigned int a, b, c,例如:a / 10, b

JavaScript 32位整型无符号操作

在 JavaScript 中,所有整数字变量默认都是有符号整数,这意味着什么呢? 有符号整数使用 31 位表示整数的数值,用第 32 位表示整数的符号,0 表示正数,1 表示负数. 数值范围从 -2^31 - 2^31-1 即 -2147483648 到 2147483647. JavaScript 进行位操作时,是采用32位 有符号 整型,这意味着其转换的结果也是32位有符号整型. 有些时候,我们进行移位会出现意想不到的结果,以下是C语言 与 JS 的对比. C语言 1 unsigned in

位向量 补码与无符号 加法与乘法 CSAPP学习笔记

计算机中用位来表示整数,一种方式只能表示非负数,一种可以表示有符号数. 无符号数编码: 补码编码: 由上面的定义可以知道补码与无符号之间的对应关系(见下式),最高位为0时,补码与无符号表示是一样的,而最高位为1时,举个例子,补码表示的-1对应于无符号数的4294967295(这里指的是32位数) . 在整数运算之前必须先了解 整数的扩展和截断 扩展分为零扩展和符号扩展,零扩展是简单的在表示的开头添加0,适用于无符号数的扩展.而符号扩展在表示中添加最高有效位值的副本,适用于补码的扩展.比如4位的1

整数表示 补码与无符号 加法与乘法 CSAPP学习笔记

计算机中用位来表示整数,一种方式只能表示非负数,一种可以表示有符号数. 无符号数编码: 补码编码: 由上面的定义可以知道补码与无符号之间的对应关系(见下式),最高位为0时,补码与无符号表示是一样的,而最高位为1时,举个例子,补码表示的-1对应于无符号数的4294967295 . 在整数运算之前必须先了解 整数的扩展和截断 扩展分为零扩展和符号扩展,零扩展是简单的在表示的开头添加0,适用于无符号数的扩展.而符号扩展在表示中添加最高有效位值的副本,适用于补码的扩展.比如4位的1101扩展成8位,即1