汇编语言只用ADD指令实现整数和浮点数的加减乘法

汇编语言只用ADD指令实现整数和浮点数的加减乘法
汇编语言只用ADD指令实现整数和浮点数的加减乘法

课程项目报告

一、要求:

利用汇编语言完成以下功能:

通过键盘输入二进制指令,对指令译码,完成相应的加、减和乘操作全过程。只能使用汇编的ADD指令,不能使用汇编已有的其他加法、加法和乘法指令。

*指令格式一为:

*

其中00为加法,01为减法,10为乘法

*指令格式二为:

*

其中当操作码为11,第二定点数全为0,第一定点数分别为000,001,010时,分别执行第一浮点数和第二浮点数的加、减和乘法操作,浮点数格式采用IEEE754标准。

二、程序流程:

1.通过中断输入要译码的二进制字符流;

2.选择其前8位合成1个数(如00101001就可合并为29H),先对其

进行要运算的判定。

通过依次移位将最左端的值放进CF位,判断其值为0或1跳转到相应的位置进行运算;

3.此程序显然有六种运算:

1)整数加法:最简单的一种,将两个操作数通过移位和设定寄存器的初值来获得,然后只需调用加法使两个寄存器相加即可,

将结果存入result内存单元中。并通过中断对结果进行输出到

屏幕的显示。

2)整数减法:取数和加法一致,但由于规定只能使用加法指令,因此必须先将减数的值进行求补(取反加1),再进行加法指令

即可,将结果存入result内存单元中。并通过中断对结果进行

输出到屏幕的显示。

3)整数乘法:利用硬件实现乘法的思想,通过判断第二个操作数的未判断的较低位决定是加被乘数还是加0的操作,然后将结

果右移,直到将操作数的所有位判断完毕(最后一位不移位),

将结果存入result内存单元中。并通过中断对结果进行输出到屏幕的显示。

4)浮点数加法:前面取了前8位归并后,将指针的位置保留下来,现在将其指针弹栈继续对剩下的输入的字符进行操作。首先调用子程序将剩下的输入字符流存入内存以待使用(将字符流转变成数值并组成一个完整的数字,即浮点数有三个数:1位的数符,8位的阶码,23位的数值)。此次运算严格按照浮点数的运算进行,即先对阶(阶码小的向阶码大的对齐)->取数运算(由于输入的是二进制字符流,因此在运算之前需根据数符对数值进行补码操作,而且由于有23位数值,通用寄存器只有16位,需调用两个寄存器来运算,注意低位是否有向高位的进位)->规格化,最后将阶码存到float_jie内存,数值运算结果存入result单元。并通过中断对阶码和数值进行输出显示。5)浮点数减法:及加法一样先调用中断将剩下的浮点数信息存入内存。及加法不同的是由于只能用加法指令,在操作的时候同样需先对第二个浮点数进行求补操作(取反加1),然后在进行及加法一样的操作,最后将阶码存到float_jie内存,数值运算结果存入result单元。并通过中断对阶码和数值进行输出显示。

6)浮点数乘法:及前面两个浮点数的操作一样先将剩下的浮点数信息存入内存。我们这里操作数均取得补码,因此用booth算法做乘法运算(通过移位取最低两位进行判断,如果相同则加

0,如果ynyn-1=10,则加【x】补,如果为ynyn-1=01,则加【-x】

补),通过23次的判断,进行加法操作和移位,最终得到结果,

将阶码存到float_jie内存,数值运算结果存入result单元。

并通过中断对阶码和数值进行输出显示。

三、在此给出部分运行结果:

1.整数加法

输入:

注意:指令P下面的二进制字符流严格按照要求的格式进行输入

输出:

注意:由于我在存储的时候将result内存设为了dd型,而我在存的时候存在了高位,在内存中是以大端格式存储,对于此题我们只用到了三位数的加法,显然可以看出最后结果为02(001+001),正确。

2.整数减法

输入:

输出:

这里和整数加法是一样的输出设置,因此结果为01(010-001),正确。

4.整数乘法

输入:

输出:

输出为1(001*001),结果正确。

5.浮点数加法:

注意:这里输入并未输入特别规范的移码表示其阶码的格式,这样输入比较简单,而且在两个阶码均正的情况下不会涉及到大小对阶时判断错误的情况。

输出:

注意:阶码为0(浮点数1和2的阶码均为0的结果)

注意:浮点数23位数值的计算结果为002,这里我将其设为十进制,但在用的时候还必须将其转变为二进制才可用,例如这个的最后结果应该为1.00000000000000000000010*2^0,可知结果正确。

附录:代码

data segment

user_string db 75,?,72 dup(?)

float1_sign db ?

float1_jie db ?

float1_figure dd ?

float1_figure_bu dd ?

float2_sign db ?

float2_jie db ?

float2_figure dd ?

float_jie db ?,'$'

result dd ?,'$'

;exitt dw "溢出$"

tempr dw ?

data ends

code segment

main proc far

assume ds:data,cs:code

start:mov ax,data

mov ds,ax

call inputBAndSelect8

push bx;将下一字符的地址放入堆栈 mov bh,ah;将输入的字符放到bh rol bx,1;取第一个操作码到cf

jnc INTEGER;CF=0

jc others;CF=1

INTEGER:

rol bx,1;取第二个操作码到cf

jnc INTEGERadd;CF=0

jc INTEGERsub;CF=1 INTEGERadd:

call INTEGER_ADD INTEGERsub:

call INTEGER_SUB

others:

rol bx,1;取第二个操作码到cf

jnc INTEGERmul;CF=0

jnz FLOAT;CF=1

INTEGERmul:

call INTEGER_MUL

FLOAT:

mov bl,0

mov cl,3

rol bx,cl;取第一个定点数放到bl mov ch,bl;转存到ch

mov bl,0

rol bx,cl;取第二个定点数放到bl mov cl,bl;转存到cl

and cx,cx

jz FLOATadd

test cx,10h

jz FLOATsub

test cx,20h

jz FLOATmul

FLOATadd:

call FLOAT_ADD

FLOATsub:

call FLOAT_SUB

FLOATmul:

call FLOAT_MUL

ret

main endp

;-----------------------------------------------------

;=================================================== ==

;INPUT BINARY STREAM(读入字符串,并取出前8个字符到ah 寄存器中,bx指向字符串的下一字符)

inputBAndSelect8 proc near

lea bx,user_string

mov ah,0ah

int 21h

mov ch,0

add bx,2;指向真正字符串开始的位置

mov ah,0

mov cl,8

add cl,255

beginin:

mov al,[bx]

add al,208;将字符串变为数值

mov [bx],al

add ah,al;将输入的字符串组成一个数

rol ah,1

add bx,1

loop beginin

mov al,[bx];最后一次不用移位

add al,208;将字符串变为数值

mov [bx],al

add ah,al;将输入的字符串组成一个数

add bx,1;指向下一个字符

ret

inputBAndSelect8 endp

;==================================================

;==================================================

;整数加法,bh中只有两个操作数,各三位,最后结果存放到result内存

INTEGER_ADD proc near

mov bl,0

mov cl,3

rol bx,cl;取第一个操作数放到bl

mov ch,bl;转存到ch

mov bl,0

rol bx,cl;取第二个操作数放到bl

mov cl,bl;转存到ch

add ch,cl;第一个操作数和第二个操作数做加法

mov result,ch

call DISPLAY_RESULT

ret

INTEGER_ADD endp

;==================================================

;==================================================

;整数减法,bh中只有两个操作数,各三位,最后结果存放到result内存

INTEGER_SUB proc near

mov bl,0

mov cl,3

rol bx,cl;取第一个操作数放到bl

mov ch,bl;转存到cl

mov bl,0

rol bx,cl;取第二个操作数放到bl

mov cl,bl;转存到ch

not cl;将第二个操作数取反

add cl,1;取反加1求补

add ch,cl;第一个操作数和第二个操作数的补相加

call DISPLAY_RESULT

ret

INTEGER_SUB endp

;==================================================

;=================================================== =

;整数乘法,bh中只有两个操作数,各三位,最后结果存放到result内存

INTEGER_MUL proc near

mov bl,0

mov cl,3

rol bx,cl;取第一个操作数放到bl

mov al,bl;转存到al

mov bl,0

rol bx,cl;取第二个操作数放到bl

mov dx,0;初始化结果为0

beginmu:

shr bx,1;判断最后一位是否为1

jc add1;CF=1

ror dx,1;将最后总和右移,为下一步做铺垫

loop beginmu

rol dx,cl;将最后的结果放到dh保存

mov result,dh;再移到result

call DISPLAY_RESULT

ret

add1:

add dh,al ;加第一操作数

ror dx,1;将最后总和右移,为下一步做铺垫

loop beginmu

mov cl,3

rol dx,cl;将最后的结果放到dh保存

mov result,dh;再移到result

call DISPLAY_RESULT

ret

INTEGER_MUL endp

;================================================== ;================================================== ;浮点数的加法,取相应的数据进行对阶-运算-右归操作FLOAT_ADD proc near

call SAVE_FLOAT_DATA

mov ch,float1_jie

mov cl,float2_jie

not ch

add ch,1

add cl,ch

cmp cl,0

jg DUI_JIE_a;第二个浮点数的阶码比较大 cmp cl,0

jz DUI_JIE2_a

not cl

add cl,1

cmp cl,0

jg DUI_JIE1_a

DUI_JIE_a:

mov ch,float2_jie

mov float_jie,ch

mov ax,float1_figure

mov bx,float1_figure+2

xor ch,ch

beginmove1_a:

shr bx,1

shr ax,1

jc adjust_a

loop beginmove1_a

mov cx,float2_figure mov dx,float2_figure+2 jmp d_add

adjust_a:

add bx,10h

loop beginmove1_a

mov cx,float2_figure mov dx,float2_figure+2 jmp d_add

DUI_JIE1_a:

mov ch,float1_jie

mov float_jie,ch

mov ax,float2_figure mov bx,float2_figure+2 xor ch,ch

beginmove2_a:

shr bx,1

shr ax,1

jc adjust1_a

loop beginmove2_a

mov cx,float1_figure mov dx,float1_figure+2

jmp d_add

adjust1_a:

add bx,10h

loop beginmove2_a

mov cx,float1_figure

mov dx,float1_figure+2

jmp d_add

DUI_JIE2_a:

mov ax,float1_jie

mov float_jie,ax

mov ax,float1_figure

mov bx,float1_figure+2

mov cx,float2_figure

mov dx,float2_figure+2

;--------------------------------------;将各个数变为补码

d_add:

mov ah,float1_sign

test ah,1

jz d_add1

mov ah,0

not ax

not bx

add bx,1

jnc d_add1

add ax,1

d_add1:

mov ch,float2_sign

test ch,1

jz d_add2

mov ch,0

not cx

not dx

add dx,1

jnc d_add2

add cx,1

;--------------------------------------;运算

d_add2:

add ax,cx

add bx,dx

jc adjust2_a

test ax,80h

jnz YOU_GUI_a

mov result,ax

mov result+2,bx

call DISPLAY_JIE call DISPLAY_RESULT

ret

adjust2_a:

add ax,1

test ax,80h

jnz YOU_GUI_a

mov result,ax

mov result+2,bx

call DISPLAY_JIE call DISPLAY_RESULT

ret

YOU_GUI_a:

shr bx,1

shr ax,1

jc adjust3_a

mov cx,float_jie add cx,1

cmp cx,0100h

jz exit_a

mov float_jie,cx

mov result,ax

mov result+2,bx

call DISPLAY_JIE

call DISPLAY_RESULT

ret

adjust3_a:

add bx,8000h

mov cx,float_jie

add cx,1

cmp cx,0100h

jz exit_a

mov float_jie,cx

mov result,ax

mov result+2,bx

call DISPLAY_JIE

call DISPLAY_RESULT

exit_a:

;call OVERFLOW

ret

FLOAT_ADD endp

;===================================================

;=================================================== ;将剩余数据存到相应内存

SAVE_FLOAT_DATA proc near

pop bx

;;;;;;;;;;;;将第一个浮点数的信息存入内存;;;;;;;;;;;;;;;;;;;

mov al,[bx]

add al,208

mov [bx],al

mov [float1_sign],al

inc bx

xor ch,ch

mov cl,7

mov ax,0

beginf1_jie:

mov al,[bx]

add al,208

mov [bx],al

add ah,al;将输入的字符串组成一个数

rol ah,1

add bx,1;指向下一个字符

loop beginf1_jie

相关主题
相关文档
最新文档