汇编语言只用ADD指令实现整数和浮点数的加减乘法.docx
《汇编语言只用ADD指令实现整数和浮点数的加减乘法.docx》由会员分享,可在线阅读,更多相关《汇编语言只用ADD指令实现整数和浮点数的加减乘法.docx(33页珍藏版)》请在冰豆网上搜索。
汇编语言只用ADD指令实现整数和浮点数的加减乘法
课程项目报告
一、要求:
利用汇编语言完成以下功能:
通过键盘输入二进制指令,对指令译码,完成相应的加、减和乘操作全过程。
只能使用汇编的ADD指令,不能使用汇编已有的其他加法、加法和乘法指令。
*指令格式一为:
*操作码
*第一操作数
*第二操作数
*76
*543
*210
*
其中00为加法,01为减法,10为乘法
*指令格式二为:
*操作码
*第一定点数
*第二定点数
*第一浮点数
*第二浮点数
*7170
*696867
*666564
*63………32
*31………..0
*
其中当操作码为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,可知结果正确。
附录:
代码
datasegment
user_stringdb75,?
72dup(?
)
float1_signdb?
float1_jiedb?
float1_figuredd?
float1_figure_budd?
float2_signdb?
float2_jiedb?
float2_figuredd?
float_jiedb?
'$'
resultdd?
'$'
;exittdw"溢出$"
temprdw?
dataends
codesegment
mainprocfar
assumeds:
data,cs:
code
start:
movax,data
movds,ax
callinputBAndSelect8
pushbx;将下一字符的地址放入堆栈
movbh,ah;将输入的字符放到bh
rolbx,1;取第一个操作码到cf
jncINTEGER;CF=0
jcothers;CF=1
INTEGER:
rolbx,1;取第二个操作码到cf
jncINTEGERadd;CF=0
jcINTEGERsub;CF=1
INTEGERadd:
callINTEGER_ADD
INTEGERsub:
callINTEGER_SUB
others:
rolbx,1;取第二个操作码到cf
jncINTEGERmul;CF=0
jnzFLOAT;CF=1
INTEGERmul:
callINTEGER_MUL
FLOAT:
movbl,0
movcl,3
rolbx,cl;取第一个定点数放到bl
movch,bl;转存到ch
movbl,0
rolbx,cl;取第二个定点数放到bl
movcl,bl;转存到cl
andcx,cx
jzFLOATadd
testcx,10h
jzFLOATsub
testcx,20h
jzFLOATmul
FLOATadd:
callFLOAT_ADD
FLOATsub:
callFLOAT_SUB
FLOATmul:
callFLOAT_MUL
ret
mainendp
;-----------------------------------------------------
;=====================================================
;INPUTBINARYSTREAM(读入字符串,并取出前8个字符到ah寄存器中,bx指向字符串的下一字符)
inputBAndSelect8procnear
leabx,user_string
movah,0ah
int21h
movch,0
addbx,2;指向真正字符串开始的位置
movah,0
movcl,8
addcl,255
beginin:
moval,[bx]
addal,208;将字符串变为数值
mov[bx],al
addah,al;将输入的字符串组成一个数
rolah,1
addbx,1
loopbeginin
moval,[bx];最后一次不用移位
addal,208;将字符串变为数值
mov[bx],al
addah,al;将输入的字符串组成一个数
addbx,1;指向下一个字符
ret
inputBAndSelect8endp
;==================================================
;==================================================
;整数加法,bh中只有两个操作数,各三位,最后结果存放到result内存
INTEGER_ADDprocnear
movbl,0
movcl,3
rolbx,cl;取第一个操作数放到bl
movch,bl;转存到ch
movbl,0
rolbx,cl;取第二个操作数放到bl
movcl,bl;转存到ch
addch,cl;第一个操作数和第二个操作数做加法
movresult,ch
callDISPLAY_RESULT
ret
INTEGER_ADDendp
;==================================================
;==================================================
;整数减法,bh中只有两个操作数,各三位,最后结果存放到result内存
INTEGER_SUBprocnear
movbl,0
movcl,3
rolbx,cl;取第一个操作数放到bl
movch,bl;转存到cl
movbl,0
rolbx,cl;取第二个操作数放到bl
movcl,bl;转存到ch
notcl;将第二个操作数取反
addcl,1;取反加1求补
addch,cl;第一个操作数和第二个操作数的补相加
movresult,ch
callDISPLAY_RESULT
ret
INTEGER_SUBendp
;==================================================
;====================================================
;整数乘法,bh中只有两个操作数,各三位,最后结果存放到result内存
INTEGER_MULprocnear
movbl,0
movcl,3
rolbx,cl;取第一个操作数放到bl
moval,bl;转存到al
movbl,0
rolbx,cl;取第二个操作数放到bl
movdx,0;初始化结果为0
beginmu:
shrbx,1;判断最后一位是否为1
jcadd1;CF=1
rordx,1;将最后总和右移,为下一步做铺垫
loopbeginmu
movcl,3
roldx,cl;将最后的结果放到dh保存
movresult,dh;再移到result
callDISPLAY_RESULT
ret
add1:
adddh,al;加第一操作数
rordx,1;将最后总和右移,为下一步做铺垫
loopbeginmu
movcl,3
roldx,cl;将最后的结果放到dh保存
movresult,dh;再移到result
callDISPLAY_RESULT
ret
INTEGER_MULendp
;==================================================
;==================================================
;浮点数的加法,取相应的数据进行对阶-运算-右归操作
FLOAT_ADDprocnear
callSAVE_FLOAT_DATA
movch,float1_jie
movcl,float2_jie
notch
addch,1
addcl,ch
cmpcl,0
jgDUI_JIE_a;第二个浮点数的阶码比较大
cmpcl,0
jzDUI_JIE2_a
notcl
addcl,1
cmpcl,0
jgDUI_JIE1_a
DUI_JIE_a:
movch,float2_jie
movfloat_jie,ch
movax,float1_figure
movbx,float1_figure+2
xorch,ch
beginmove1_a:
shrbx,1
shrax,1
jcadjust_a
loopbeginmove1_a
movcx,float2_figure
movdx,float2_figure+2
jmpd_add
adjust_a:
addbx,10h
loopbeginmove1_a
movcx,float2_figure
movdx,float2_figure+2
jmpd_add
DUI_JIE1_a:
movch,float1_jie
movfloat_jie,ch
movax,float2_figure
movbx,float2_figure+2
xorch,ch
beginmove2_a:
shrbx,1
shrax,1
jcadjust1_a
loopbeginmove2_a
movcx,float1_figure
movdx,float1_figure+2
jmpd_add
adjust1_a:
addbx,10h
loopbeginmove2_a
movcx,float1_figure
movdx,float1_figure+2
jmpd_add
DUI_JIE2_a:
movax,float1_jie
movfloat_jie,ax
movax,float1_figure
movbx,float1_figure+2
movcx,float2_figure
movdx,float2_figure+2
;--------------------------------------
;将各个数变为补码
d_add:
movah,float1_sign
testah,1
jzd_add1
movah,0
notax
notbx
addbx,1
jncd_add1
addax,1
d_add1:
movch,float2_sign
testch,1
jzd_add2
movch,0
notcx
notdx
adddx,1
jncd_add2
addcx,1
;--------------------------------------
;运算
d_add2:
addax,cx
addbx,dx
jcadjust2_a
testax,80h
jnzYOU_GUI_a
movresult,ax
movresult+2,bx
callDISPLAY_JIE
callDISPLAY_RESULT
ret
adjust2_a:
addax,1
testax,80h
jnzYOU_GUI_a
movresult,ax
movresult+2,bx
callDISPLAY_JIE
callDISPLAY_RESULT
ret
YOU_GUI_a:
shrbx,1
shrax,1
jcadjust3_a
movcx,float_jie
addcx,1
cmpcx,0100h
jzexit_a
movfloat_jie,cx
movresult,ax
movresult+2,bx
callDISPLAY_JIE
callDISPLAY_RESULT
ret
adjust3_a:
addbx,8000h
movcx,float_jie
addcx,1
cmpcx,0100h
jzexit_a
movfloat_jie,cx
movresult,ax
movresult+2,bx
callDISPLAY_JIE
callDISPLAY_RESULT
exit_a:
;callOVERFLOW
ret
FLOAT_ADDendp
;===================================================
;===================================================
;将剩余数据存到相应内存
SAVE_FLOAT_DATAprocnear
popbx
;;;;;;;;;;;;将第一个浮点数的信息存入内存;;;;;;;;;;;;;;;;;;;
moval,[bx]
addal,208
mov[bx],al
mov[float1_sign],al
incbx
xorch,ch
movcl,7
movax,0
beginf1_jie:
moval,[bx]
addal,208
mov[bx],al
addah,al;将输入的字符串组成一个数
rolah,1
addbx,1;指向下一个字符
loopbeginf1_jie
moval,[bx]
addal,208
mov[bx],al
addah,al;将输入的字符串组成一个数
;rolah,1
addbx,1;指向下一个字符
pushbx
leabx,float1_jie
;addbx,2
mov[bx],ah
popbx
movcl,15
movax,0
movdx,0
beginf1_figure1:
moval,[bx]
addal,208
mov[bx],al
adddx,al;将输入的字符串组成一个数
roldx,1
addbx,1;指向下一个字符
loopbeginf1_figure1
movcl,8
movch,0
beginf1_figure2:
moval,[bx]
addal,208
mov[bx],al
adddx,al;将输入的字符串组成一个数
shldx,1
jcah1
shlah,1
addah,0
incbx
loopbeginf1_figure2
jmpshr1
ah1:
shlah,1
addah,1
incbx
loopbeginf1_figure2
;addbx,1;指向下一个字符
shr1:
shrah,1
jcshr11
shrdx,1
jmpsave1
shr11:
shrdx,1
adddx,80h
save1:
;pushbx
;leabx,float1_figure
movfloat1_figure+2,dx
movfloat1_figure,ah
;popbx
;;;;;;;;;;;;将第二个浮点数的信息存入内存;;;;;;;;;;;;;;;;;;;;;
moval,[bx]
addal,208
mov[bx],al
mov[float2_sign],al
incbx
xorch,ch
movcl,7
movax,0
beginf2_jie:
moval,[bx]
addal,208
mov[bx],al
addah,al;将输入的字符串组成一个数
rolah,1
addbx,1;指向下一个字符
loopbeginf2_jie
moval,[bx]
addal,208
mov[bx],al
addah,al;将输入的字符串组成一个数
;rolah,1
addbx,1;指向下一个字符
pushbx
leabx,float2_jie
;addbx,2
mov[bx],ah
popbx
movcl,15
movax,0
movdx,0
beginf2_figure1:
moval,[bx]
addal,208
mov[bx],al
adddx,al;将输入的字符串组成一个数
roldx,1
addbx,1;指向下一个字符
loopbeginf2_figure1
movcl,8
movch,0
beginf2_figure2:
moval,[bx]
addal,208
mov[bx],al
adddx,al;将输入的字符串组成一个数
shldx,1
jcah2
shlah,1
addah,0
incbx
loopbeginf2_figure2
jmpshr2
ah2:
shlah,1
addah,1
incbx
loopbeginf2_figure2
;addbx,1;指向下一个字符
shr2:
shrah,1
jcshr21
shrdx,1
jmpsave2
shr21:
shrdx,1
adddx,80h
save2:
;pushbx
;leabx,float2_figure
movfloat2_figure+2,dx
movfloat2_figure,ah
ret
SAVE_FLOAT_DATAendp
;===================================================
;===================================================
;浮点数的减法,到相应内存取数进行对阶-运算-右归操作
FLOAT_SUBprocnear
callSAVE_FLOAT_DATA
movch,float1_jie
movcl,float2_jie
notch
addch,1
addcl,ch
cmpcl,0
jgDUI_JIE_s;第二个浮点数的阶码比较大
cmpcl,0
jzDUI_JIE2_s
notcl
addcl,1
cmpc