汇编语言实现用16位乘法指令完成32位无符号数乘法
南京事业单位招聘-上海交大研招网
《微型计算机原理与接口技术》实验报告
一、程序设计
题目一
三十二位无符号乘法
1 设计分析:
(1)程序设计任务:
用十六位乘法指令完成三十二位无符号数乘法(结果64位)。
使用MUL指令,完成双字无符号数乘法程序,要求乘数和被
乘数从键盘输入,结果显示于屏幕上。
(2)程序设计要求:
1)从键盘输入两个乘数(十六进制)
2)结果显示于屏幕上(十六进制)
(3)程序设计过程:
1)
定义数据段用于开辟缓冲区存储输入数据、输出数据和乘积。
2)从键盘分别输入两个八位数字
符(三十二字节)存入缓冲区(分4次输入,每次输入
4个字符,前两次为被乘数的高位与低位,后两次
为乘数的高位与低位)
3)对缓冲区输入的字符进行处理,让Ascal码转换为数值本身的数值。
4)把三十二位分割成两位十六位,分别对其进行十六位的乘法。
5)将四个十六位乘法的乘积按照各自的位相加的最终乘积
6)对所得结果进行处理,让Ascal码转换为数值本身的数值
7)将结果向屏幕输出。
2、算法(一个框代表16位2进制数)
3、 X2
X1
16 16
y2
y1
16 16
16
16
16
16 16
16
16
16
16 16 16 16
P+6 p+4 p+2 p
4、
程序流程图:
开始
初始化
输入被乘数的
高位的4个字符
X2
输入被乘数的
低位的4个字符
X1
输入乘数的
高位的4个字符
y2
输入乘数的
低位的4个字符
y1
开始运算乘法
被乘数低位4个字符x1和
乘数低位4个字符y1相乘结
果低位存入p,高位存入p+2
被乘数高位4个字符x2和
乘数低位4个字符y1相乘
结果低位存入p+2,高位存入
p+4
被乘数低位4个字符x1和
乘数高位4个字符y2相乘
结果低位存入p+2,高位存入
p+4
被乘数高位4个字符x2和
乘数高位4个字符y2相乘
结果低位存入p+4,高位存入
p+6
5、 测试数据与运行结果:
输入被乘数的高位的4个字符X2:
乘积相加
输出结果
输入被乘数的低位的4个字符X1:
输入乘数的高位的4个字符y2:
输入乘数的低位的4个字符y1:
运行结果:
6、 程序源代码及注解:
ddata segment
x1
dw 16 dup(?)
x2 dw 16 dup(?)
y1 dw 16
dup(?)
y2 dw 16 dup(?)
p dw 30 dup(?)
keybuf db 10 dup(?)
ddata ends
; 定义数据段
ccode segment
assume
cs:ccode,ds:ddata
start:mov ax,ddata
mov ds,ax
mov dx,offset keybuf
mov bx,dx
mov [bx],byte ptr 9
mov ah,0ah
int 21h
mov
ah,[bx+2]
mov al,[bx+3]
shl
al,4
shr ax,4
mov dh,al
mov ah,[bx+4]
mov al,[bx+5]
shl al,4
shr ax,4
mov dl,al
mov x2,dx
mov dx,offset keybuf
mov bx,dx
mov [bx],byte ptr 9
mov ah,0ah
int 21h
mov ah,[bx+2]
mov al,[bx+3]
shl al,4
shr
ax,4
mov dh,al
mov ah,[bx+4]
mov al,[bx+5]
shl al,4
shr ax,4
;
输入被乘数的高位的4个字符x2
mov dl,al
mov x1,dx
;
输入被乘数的低位的4个字符x1
mov
dx,offset keybuf
mov bx,dx
mov
[bx],byte ptr 9
mov ah,0ah
int
21h
mov ah,[bx+2]
mov
al,[bx+3]
shl al,4
shr ax,4
mov dh,al
mov ah,[bx+4]
mov al,[bx+5]
shl al,4
shr
ax,4
mov dl,al
mov y2,dx
;
mov dx,offset keybuf
mov
bx,dx
mov [bx],byte ptr 9
mov
ah,0ah
int 21h
mov ah,[bx+2]
mov al,[bx+3]
shl al,4
shr ax,4
mov dh,al
mov
ah,[bx+4]
mov al,[bx+5]
shl
al,4
shr ax,4
mov dl,al
mov y1,dx
mov ax,x1
mov dx,y1
mul dx
mov
[p],ax
mov [p+2],dx
输入乘数的高位的4个字符y2
输入乘数的低位的4个字符y1
被乘数低位4字符x1和乘数低位4字符y1相乘结果低位
存入p,高位存入p+2
mov ax,x2
mov dx,y1
mul dx
add [p+2],ax
adc [p+4],dx
被乘数高位4字符x2和乘数低位4字符y1相乘结果低位存入p+2,高
位存入p+4
mov ax,x1
mov dx,y2
mul dx
add
[p+2],ax
adc [p+4],dx
adc [p+6],0
;
被乘数低位4个字符x1和乘数高位4个字符y2相乘结果低位存入p+2,
高位存入p+4
mov ax,x2
mov dx,y2
mul dx
add [p+4],ax
adc [p+6],dx
被乘数高位4个字符x2和乘数高位4个字符y2相乘结果低位存入p+4,
高位存入p+6
mov al,byte ptr p+7 ;输出
call
dispal
mov al,byte ptr p+6
call dispal
mov al,byte ptr p+5
call dispal
mov
al,byte ptr p+4
call dispal
mov al,byte
ptr p+3
call dispal
mov al,byte ptr p+2
call dispal
mov al,byte ptr p+1
call
dispal
mov al,byte ptr p
call dispal
mov ah,4ch
int 21h
dispal
proc 子程序屏幕输出过程
push
cx
push dx
push
ax
mov cl,4
shr al,cl
or al,30h
cmp al,3ah
jb br1
add al,7
BR1: mov dl,al
mov ah,2
int 21h
pop ax
and al,0fh
or al,30h
cmp
al,3ah
jb br2
add al,7
br2: mov dl,al
mov ah,2
int 21h
pop dx
pop cx
ret
dispal endp
ccode ends
end start
题目二 递归调用子程序设计
1、设计分析:
(1)程序设计任务:
有n个人坐在一起,第n个人比第n-1个人大h岁。第n
-1个人比第n-2个人大h岁。
以此类推,第2个人比第1个人大h岁。第1个人m岁。请问第n个人
多大。用递归调用
的方法设计程序完成题目。
(2)设计要求:
1)从键盘输入人数、第一个人的年龄和年龄差距
2)结果显示于屏幕上
2、程序流程图:
开始
初始化数据段与
堆栈段
初始化数据段与
堆栈段
输入p1语句,输
入数字到AL
al和3aH做比较,目
的是为了判断是不
是数字
小于说明是数字,与0fh大于3ah说明是字母
相与运算变成数字 或者其他,跳转到pd
比较al与47h的大小,
大于则报错小于说明
是字母
执行循环
输出
3.运行结果:
4.程序源代码及注解:
data segment
p1 db 'The number of
people:','$$'
p2 db 'The age of the
first people:','$$'
cr db 0DH,0AH,'$$'
data ends ; 定义数据段
sstack
segment stack 'stack'
dg db 100h dup(?)
sstack ends ;定义堆栈段
code
segment ;定义代码段
assume
cs:code, ds:data, ss:sstack
main proc far
;主函数
push dx
xor ax,ax
push ax
mov ax,data
mov ds,ax
;初始化程序,使数据段连接到主程序
mov AH,09
lea dx,p1
int 21h ;输出p1语句
mov ah,1
int 21h ;输入数字到AL
and al,0fh ;将数字ASCII码转换成数字
mov cl,al
;用cl寄存器存储al的值
lea dx,cr
mov ah,09
int 21h ;输出回车 换行
mov AH,09
lea dx,p2
int
21h ;输出p2语句
mov ah,1
int
21h ;读取输入给al
cmp al,3ah
;al和3aH做比较,判断是不是数字
jnl pd
;如果大于3ah说明是字母或者其他,跳转到pd
and al,0fh
;如果小于说明是数字,与0fh与运算变成数字。
back:
mov bl,al ;把al的值给bl
lea dx,cr
mov ah,09
int 21h ;输出换行
call renshu ;调用子程序renshu
mov ah,4ch
int 21h
pd: cmp
al,47h ;比较al于47h的大小,判断是字母还是其他
jnl
er ;如果大于,报错
sub al,37h
;如果小于说明是字母
call back
er: mov al,0
;er是大于大写字母时执行的,
main endp
renshu
proc ;子程序,实现递归调用
cmp cl,1
;人数减一,作为循环条件
jne age ;年龄不等于1的话执行age
mov al,bl ;把bl的值给al进行输出
call
dispal ;调用子程序的dispal
ret
age: add
bl,2 ;年龄+2
sub cl,1
;人数—1
call renshu
;调用回renshu子程序,继续判断年龄
ret
renshu
endp ;子程序结束
dispal proc
;输出语句,用于输出al中的值
push cx
push
dx
push ax ;将三个寄存器的值压入堆栈,保护起来,
mov cl,4 ;把4给cl
shr al,cl ;右移al
4位
or al,30h
cmp al,3ah
;比较al和30h
jb br1 ;跳转到br1
add al,7
br1: mov dl,al
mov
ah,2
int 21h
pop ax
;ax出栈
and al,0fh
or al,30h
cmp al,3ah
jb br2
;跳转到br2
add al,7
br2: mov dl,al
mov ah,2
int 21h
pop dx ;dx出栈
pop cx
;cx出栈
ret
dispal endp ;子程序结束
code ends ;代码段结束
end main
;函数结束。
《微型计算机原理与接口技术》实验报告
一、程序设计
题目一
三十二位无符号乘法
1 设计分析:
(1)程序设计任务:
用十六位乘法指令完成三十二位无符号数乘法(结果64位)。
使用MUL指令,完成双字无符号数乘法程序,要求乘数和被
乘数从键盘输入,结果显示于屏幕上。
(2)程序设计要求:
1)从键盘输入两个乘数(十六进制)
2)结果显示于屏幕上(十六进制)
(3)程序设计过程:
1)
定义数据段用于开辟缓冲区存储输入数据、输出数据和乘积。
2)从键盘分别输入两个八位数字
符(三十二字节)存入缓冲区(分4次输入,每次输入
4个字符,前两次为被乘数的高位与低位,后两次
为乘数的高位与低位)
3)对缓冲区输入的字符进行处理,让Ascal码转换为数值本身的数值。
4)把三十二位分割成两位十六位,分别对其进行十六位的乘法。
5)将四个十六位乘法的乘积按照各自的位相加的最终乘积
6)对所得结果进行处理,让Ascal码转换为数值本身的数值
7)将结果向屏幕输出。
2、算法(一个框代表16位2进制数)
3、 X2
X1
16 16
y2
y1
16 16
16
16
16
16 16
16
16
16
16 16 16 16
P+6 p+4 p+2 p
4、
程序流程图:
开始
初始化
输入被乘数的
高位的4个字符
X2
输入被乘数的
低位的4个字符
X1
输入乘数的
高位的4个字符
y2
输入乘数的
低位的4个字符
y1
开始运算乘法
被乘数低位4个字符x1和
乘数低位4个字符y1相乘结
果低位存入p,高位存入p+2
被乘数高位4个字符x2和
乘数低位4个字符y1相乘
结果低位存入p+2,高位存入
p+4
被乘数低位4个字符x1和
乘数高位4个字符y2相乘
结果低位存入p+2,高位存入
p+4
被乘数高位4个字符x2和
乘数高位4个字符y2相乘
结果低位存入p+4,高位存入
p+6
5、 测试数据与运行结果:
输入被乘数的高位的4个字符X2:
乘积相加
输出结果
输入被乘数的低位的4个字符X1:
输入乘数的高位的4个字符y2:
输入乘数的低位的4个字符y1:
运行结果:
6、 程序源代码及注解:
ddata segment
x1
dw 16 dup(?)
x2 dw 16 dup(?)
y1 dw 16
dup(?)
y2 dw 16 dup(?)
p dw 30 dup(?)
keybuf db 10 dup(?)
ddata ends
; 定义数据段
ccode segment
assume
cs:ccode,ds:ddata
start:mov ax,ddata
mov ds,ax
mov dx,offset keybuf
mov bx,dx
mov [bx],byte ptr 9
mov ah,0ah
int 21h
mov
ah,[bx+2]
mov al,[bx+3]
shl
al,4
shr ax,4
mov dh,al
mov ah,[bx+4]
mov al,[bx+5]
shl al,4
shr ax,4
mov dl,al
mov x2,dx
mov dx,offset keybuf
mov bx,dx
mov [bx],byte ptr 9
mov ah,0ah
int 21h
mov ah,[bx+2]
mov al,[bx+3]
shl al,4
shr
ax,4
mov dh,al
mov ah,[bx+4]
mov al,[bx+5]
shl al,4
shr ax,4
;
输入被乘数的高位的4个字符x2
mov dl,al
mov x1,dx
;
输入被乘数的低位的4个字符x1
mov
dx,offset keybuf
mov bx,dx
mov
[bx],byte ptr 9
mov ah,0ah
int
21h
mov ah,[bx+2]
mov
al,[bx+3]
shl al,4
shr ax,4
mov dh,al
mov ah,[bx+4]
mov al,[bx+5]
shl al,4
shr
ax,4
mov dl,al
mov y2,dx
;
mov dx,offset keybuf
mov
bx,dx
mov [bx],byte ptr 9
mov
ah,0ah
int 21h
mov ah,[bx+2]
mov al,[bx+3]
shl al,4
shr ax,4
mov dh,al
mov
ah,[bx+4]
mov al,[bx+5]
shl
al,4
shr ax,4
mov dl,al
mov y1,dx
mov ax,x1
mov dx,y1
mul dx
mov
[p],ax
mov [p+2],dx
输入乘数的高位的4个字符y2
输入乘数的低位的4个字符y1
被乘数低位4字符x1和乘数低位4字符y1相乘结果低位
存入p,高位存入p+2
mov ax,x2
mov dx,y1
mul dx
add [p+2],ax
adc [p+4],dx
被乘数高位4字符x2和乘数低位4字符y1相乘结果低位存入p+2,高
位存入p+4
mov ax,x1
mov dx,y2
mul dx
add
[p+2],ax
adc [p+4],dx
adc [p+6],0
;
被乘数低位4个字符x1和乘数高位4个字符y2相乘结果低位存入p+2,
高位存入p+4
mov ax,x2
mov dx,y2
mul dx
add [p+4],ax
adc [p+6],dx
被乘数高位4个字符x2和乘数高位4个字符y2相乘结果低位存入p+4,
高位存入p+6
mov al,byte ptr p+7 ;输出
call
dispal
mov al,byte ptr p+6
call dispal
mov al,byte ptr p+5
call dispal
mov
al,byte ptr p+4
call dispal
mov al,byte
ptr p+3
call dispal
mov al,byte ptr p+2
call dispal
mov al,byte ptr p+1
call
dispal
mov al,byte ptr p
call dispal
mov ah,4ch
int 21h
dispal
proc 子程序屏幕输出过程
push
cx
push dx
push
ax
mov cl,4
shr al,cl
or al,30h
cmp al,3ah
jb br1
add al,7
BR1: mov dl,al
mov ah,2
int 21h
pop ax
and al,0fh
or al,30h
cmp
al,3ah
jb br2
add al,7
br2: mov dl,al
mov ah,2
int 21h
pop dx
pop cx
ret
dispal endp
ccode ends
end start
题目二 递归调用子程序设计
1、设计分析:
(1)程序设计任务:
有n个人坐在一起,第n个人比第n-1个人大h岁。第n
-1个人比第n-2个人大h岁。
以此类推,第2个人比第1个人大h岁。第1个人m岁。请问第n个人
多大。用递归调用
的方法设计程序完成题目。
(2)设计要求:
1)从键盘输入人数、第一个人的年龄和年龄差距
2)结果显示于屏幕上
2、程序流程图:
开始
初始化数据段与
堆栈段
初始化数据段与
堆栈段
输入p1语句,输
入数字到AL
al和3aH做比较,目
的是为了判断是不
是数字
小于说明是数字,与0fh大于3ah说明是字母
相与运算变成数字 或者其他,跳转到pd
比较al与47h的大小,
大于则报错小于说明
是字母
执行循环
输出
3.运行结果:
4.程序源代码及注解:
data segment
p1 db 'The number of
people:','$$'
p2 db 'The age of the
first people:','$$'
cr db 0DH,0AH,'$$'
data ends ; 定义数据段
sstack
segment stack 'stack'
dg db 100h dup(?)
sstack ends ;定义堆栈段
code
segment ;定义代码段
assume
cs:code, ds:data, ss:sstack
main proc far
;主函数
push dx
xor ax,ax
push ax
mov ax,data
mov ds,ax
;初始化程序,使数据段连接到主程序
mov AH,09
lea dx,p1
int 21h ;输出p1语句
mov ah,1
int 21h ;输入数字到AL
and al,0fh ;将数字ASCII码转换成数字
mov cl,al
;用cl寄存器存储al的值
lea dx,cr
mov ah,09
int 21h ;输出回车 换行
mov AH,09
lea dx,p2
int
21h ;输出p2语句
mov ah,1
int
21h ;读取输入给al
cmp al,3ah
;al和3aH做比较,判断是不是数字
jnl pd
;如果大于3ah说明是字母或者其他,跳转到pd
and al,0fh
;如果小于说明是数字,与0fh与运算变成数字。
back:
mov bl,al ;把al的值给bl
lea dx,cr
mov ah,09
int 21h ;输出换行
call renshu ;调用子程序renshu
mov ah,4ch
int 21h
pd: cmp
al,47h ;比较al于47h的大小,判断是字母还是其他
jnl
er ;如果大于,报错
sub al,37h
;如果小于说明是字母
call back
er: mov al,0
;er是大于大写字母时执行的,
main endp
renshu
proc ;子程序,实现递归调用
cmp cl,1
;人数减一,作为循环条件
jne age ;年龄不等于1的话执行age
mov al,bl ;把bl的值给al进行输出
call
dispal ;调用子程序的dispal
ret
age: add
bl,2 ;年龄+2
sub cl,1
;人数—1
call renshu
;调用回renshu子程序,继续判断年龄
ret
renshu
endp ;子程序结束
dispal proc
;输出语句,用于输出al中的值
push cx
push
dx
push ax ;将三个寄存器的值压入堆栈,保护起来,
mov cl,4 ;把4给cl
shr al,cl ;右移al
4位
or al,30h
cmp al,3ah
;比较al和30h
jb br1 ;跳转到br1
add al,7
br1: mov dl,al
mov
ah,2
int 21h
pop ax
;ax出栈
and al,0fh
or al,30h
cmp al,3ah
jb br2
;跳转到br2
add al,7
br2: mov dl,al
mov ah,2
int 21h
pop dx ;dx出栈
pop cx
;cx出栈
ret
dispal endp ;子程序结束
code ends ;代码段结束
end main
;函数结束。