汇编语言只用ADD指令实现整数和浮点数的加减乘法
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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
call DISPLAY_RESULT
ret
INTEGER_ADD endp
;==================================================
;==================================================
;整数减法,bh中只有两个操作数,各三位,最后结果存放到result内存
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
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;将字符串变为数值
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
;==================================================
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
;整数乘法,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
4)浮点数加法:前面取了前8位归并后,将指针的位置保留下来,现在将其指针弹栈继续对剩下的输入的字符进行操作。首先调用子程序将剩下的输入字符流存入内存以待使用(将字符流转变成数值并组成一个完整的数字,即浮点数有三个数:1位的数符,8位的阶码,23位的数值)。此次运算严格按照浮点数的运算进行,即先对阶(阶码小的向阶码大的对齐)->取数运算(由于输入的是二进制字符流,因此在运算之前需根据数符对数值进行补码操作,而且由于有23位数值,通用寄存器只有16位,需调用两个寄存器来运算,注意低位是否有向高位的进位)->规格化,最后将阶码存到float_jie内存,数值运算结果存入result单元。并通过中断对阶码和数值进行输出显示。
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
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
inputBAndSelect8 endp
;==================================================
;==================================================
;整数加法,bh中只有两个操作数,各三位,最后结果存放到result内存
5)浮点数减法:与加法一样先调用中断将剩下的浮点数信息存入内存。与加法不同的是由于只能用加法指令,在操作的时候同样需先对第二个浮点数进行求补操作(取反加1),然后在进行与加法一样的操作,最后将阶码存到float_jie内存,数值运算结果存入result单元。并通过中断对阶码和数值进行输出显示。
6)浮点数乘法:与前面两个浮点数的操作一样先将剩下的浮点数信息存入内存。我们这里操作数均取得补码,因此用booth算法做乘法运算(通过移位取最低两位进行判断,如果相同则加0,如果ynyn-1=10,则加【x】补,如果为ynyn-1=01,则加【-x】补),通过23次的判断,进行加法操作和移位,最终得到结果,将阶码存到float_jie内存,数值运算结果存入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;第一个操作数和第二个操作数的补相加
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 ?,'$'
操作码
第一定点数
第二定点数
第一Baidu Nhomakorabea点数
第二浮点数
71 70
69 68 67
66 65 64
63………32
31………..0
其中当操作码为11,第二定点数全为0,第一定点数分别为000,001,010时,分别执行第一浮点数和第二浮点数的加、减和乘法操作,浮点数格式采用IEEE754标准。
二、程序流程:
1.通过中断输入要译码的二进制字符流;
2.选择其前8位合成1个数(如00101001就可合并为29H),先对其进行要运算的判定。
通过依次移位将最左端的值放进CF位,判断其值为0或1跳转到相应的位置进行运算;
3.此程序显然有六种运算:
1)整数加法:最简单的一种,将两个操作数通过移位和设定寄存器的初值来获得,然后只需调用加法使两个寄存器相加即可,将结果存入result内存单元中。并通过中断对结果进行输出到屏幕的显示。
2.整数减法
输入:
输出:
这里和整数加法是一样的输出设置,因此结果为01(010-001),正确。
4.整数乘法
输入:
输出:
输出为1(001*001),结果正确。
5.浮点数加法:
注意:这里输入并未输入特别规范的移码表示其阶码的格式,这样输入比较简单,而且在两个阶码均正的情况下不会涉及到大小对阶时判断错误的情况。
2)整数减法:取数和加法一致,但由于规定只能使用加法指令,因此必须先将减数的值进行求补(取反加1),再进行加法指令即可,将结果存入result内存单元中。并通过中断对结果进行输出到屏幕的显示。
3)整数乘法:利用硬件实现乘法的思想,通过判断第二个操作数的未判断的较低位决定是加被乘数还是加0的操作,然后将结果右移,直到将操作数的所有位判断完毕(最后一位不移位),将结果存入result内存单元中。并通过中断对结果进行输出到屏幕的显示。
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
;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
;==================================================
;浮点数的加法,取相应的数据进行对阶-运算-右归操作
FLOAT_ADD proc near
call SAVE_FLOAT_DATA
mov ch,float1_jie
mov cl,float2_jie
mov result,ch
call DISPLAY_RESULT
ret
INTEGER_SUB endp
;==================================================
;====================================================
课程项目报告
一、要求:
利用汇编语言完成以下功能:
通过键盘输入二进制指令,对指令译码,完成相应的加、减和乘操作全过程。只能使用汇编的ADD指令,不能使用汇编已有的其他加法、加法和乘法指令。
指令格式一为:
操作码
第一操作数
第二操作数
7 6
5 4 3
2 1 0
其中00为加法,01为减法,10为乘法
指令格式二为:
输出:
注意:阶码为0(浮点数1和2的阶码均为0的结果)
注意:浮点数23位数值的计算结果为002,这里我将其设为十进制,但在用的时候还必须将其转变为二进制才可用,例如这个的最后结果应该为1.00000000000000000000010*2^0,可知结果正确。
附录:代码
data segment
user_string db 75,?,72 dup(?)
beginmu:
shr bx,1;判断最后一位是否为1
jc add1;CF=1
ror dx,1;将最后总和右移,为下一步做铺垫
loop beginmu
mov cl,3
rol dx,cl;将最后的结果放到dh保存
mov result,dh;再移到result
call DISPLAY_RESULT
ret
jmp d_add
adjust_a:
add bx,10h
loop beginmove1_a
mov cx,float2_figure
三、在此给出部分运行结果:
1.整数加法
输入:
注意:指令P下面的二进制字符流严格按照要求的格式进行输入
输出:
注意:由于我在存储的时候将result内存设为了dd型,而我在存的时候存在了高位,在内存中是以大端格式存储,对于此题我们只用到了三位数的加法,显然可以看出最后结果为02(001+001),正确。
FLOATmul:
call FLOAT_MUL
ret
main endp
;-----------------------------------------------------
;=====================================================
;INPUT BINARY STREAM(读入字符串,并取出前8个字符到ah寄存器中,bx指向字符串的下一字符)
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:
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
call DISPLAY_RESULT
ret
INTEGER_ADD endp
;==================================================
;==================================================
;整数减法,bh中只有两个操作数,各三位,最后结果存放到result内存
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
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;将字符串变为数值
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
;==================================================
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
;整数乘法,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
4)浮点数加法:前面取了前8位归并后,将指针的位置保留下来,现在将其指针弹栈继续对剩下的输入的字符进行操作。首先调用子程序将剩下的输入字符流存入内存以待使用(将字符流转变成数值并组成一个完整的数字,即浮点数有三个数:1位的数符,8位的阶码,23位的数值)。此次运算严格按照浮点数的运算进行,即先对阶(阶码小的向阶码大的对齐)->取数运算(由于输入的是二进制字符流,因此在运算之前需根据数符对数值进行补码操作,而且由于有23位数值,通用寄存器只有16位,需调用两个寄存器来运算,注意低位是否有向高位的进位)->规格化,最后将阶码存到float_jie内存,数值运算结果存入result单元。并通过中断对阶码和数值进行输出显示。
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
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
inputBAndSelect8 endp
;==================================================
;==================================================
;整数加法,bh中只有两个操作数,各三位,最后结果存放到result内存
5)浮点数减法:与加法一样先调用中断将剩下的浮点数信息存入内存。与加法不同的是由于只能用加法指令,在操作的时候同样需先对第二个浮点数进行求补操作(取反加1),然后在进行与加法一样的操作,最后将阶码存到float_jie内存,数值运算结果存入result单元。并通过中断对阶码和数值进行输出显示。
6)浮点数乘法:与前面两个浮点数的操作一样先将剩下的浮点数信息存入内存。我们这里操作数均取得补码,因此用booth算法做乘法运算(通过移位取最低两位进行判断,如果相同则加0,如果ynyn-1=10,则加【x】补,如果为ynyn-1=01,则加【-x】补),通过23次的判断,进行加法操作和移位,最终得到结果,将阶码存到float_jie内存,数值运算结果存入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;第一个操作数和第二个操作数的补相加
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 ?,'$'
操作码
第一定点数
第二定点数
第一Baidu Nhomakorabea点数
第二浮点数
71 70
69 68 67
66 65 64
63………32
31………..0
其中当操作码为11,第二定点数全为0,第一定点数分别为000,001,010时,分别执行第一浮点数和第二浮点数的加、减和乘法操作,浮点数格式采用IEEE754标准。
二、程序流程:
1.通过中断输入要译码的二进制字符流;
2.选择其前8位合成1个数(如00101001就可合并为29H),先对其进行要运算的判定。
通过依次移位将最左端的值放进CF位,判断其值为0或1跳转到相应的位置进行运算;
3.此程序显然有六种运算:
1)整数加法:最简单的一种,将两个操作数通过移位和设定寄存器的初值来获得,然后只需调用加法使两个寄存器相加即可,将结果存入result内存单元中。并通过中断对结果进行输出到屏幕的显示。
2.整数减法
输入:
输出:
这里和整数加法是一样的输出设置,因此结果为01(010-001),正确。
4.整数乘法
输入:
输出:
输出为1(001*001),结果正确。
5.浮点数加法:
注意:这里输入并未输入特别规范的移码表示其阶码的格式,这样输入比较简单,而且在两个阶码均正的情况下不会涉及到大小对阶时判断错误的情况。
2)整数减法:取数和加法一致,但由于规定只能使用加法指令,因此必须先将减数的值进行求补(取反加1),再进行加法指令即可,将结果存入result内存单元中。并通过中断对结果进行输出到屏幕的显示。
3)整数乘法:利用硬件实现乘法的思想,通过判断第二个操作数的未判断的较低位决定是加被乘数还是加0的操作,然后将结果右移,直到将操作数的所有位判断完毕(最后一位不移位),将结果存入result内存单元中。并通过中断对结果进行输出到屏幕的显示。
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
;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
;==================================================
;浮点数的加法,取相应的数据进行对阶-运算-右归操作
FLOAT_ADD proc near
call SAVE_FLOAT_DATA
mov ch,float1_jie
mov cl,float2_jie
mov result,ch
call DISPLAY_RESULT
ret
INTEGER_SUB endp
;==================================================
;====================================================
课程项目报告
一、要求:
利用汇编语言完成以下功能:
通过键盘输入二进制指令,对指令译码,完成相应的加、减和乘操作全过程。只能使用汇编的ADD指令,不能使用汇编已有的其他加法、加法和乘法指令。
指令格式一为:
操作码
第一操作数
第二操作数
7 6
5 4 3
2 1 0
其中00为加法,01为减法,10为乘法
指令格式二为:
输出:
注意:阶码为0(浮点数1和2的阶码均为0的结果)
注意:浮点数23位数值的计算结果为002,这里我将其设为十进制,但在用的时候还必须将其转变为二进制才可用,例如这个的最后结果应该为1.00000000000000000000010*2^0,可知结果正确。
附录:代码
data segment
user_string db 75,?,72 dup(?)
beginmu:
shr bx,1;判断最后一位是否为1
jc add1;CF=1
ror dx,1;将最后总和右移,为下一步做铺垫
loop beginmu
mov cl,3
rol dx,cl;将最后的结果放到dh保存
mov result,dh;再移到result
call DISPLAY_RESULT
ret
jmp d_add
adjust_a:
add bx,10h
loop beginmove1_a
mov cx,float2_figure
三、在此给出部分运行结果:
1.整数加法
输入:
注意:指令P下面的二进制字符流严格按照要求的格式进行输入
输出:
注意:由于我在存储的时候将result内存设为了dd型,而我在存的时候存在了高位,在内存中是以大端格式存储,对于此题我们只用到了三位数的加法,显然可以看出最后结果为02(001+001),正确。
FLOATmul:
call FLOAT_MUL
ret
main endp
;-----------------------------------------------------
;=====================================================
;INPUT BINARY STREAM(读入字符串,并取出前8个字符到ah寄存器中,bx指向字符串的下一字符)
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: