8086汇编(一)
实验内容
- 编写一个8位十进制整数(用压缩的BCD码表示)加法, 两个整数保存在NUM1和NUM2中,结果保存在SUM中。
;sum1.asm
data segment
num1 db 23H, 45H, 67H, 89H ;Integer 0x89674523
num2 db 49H, 25H, 13H, 19H ;Integer 0x19132549
sum db 4 dup(?)
data ends
code segment
assume cs:code, ds:data
start:
mov ax,data
mov ds, ax
lea bx,num1
mov si,bx
lea bx,num2
mov di,bx
lea bx,sum
call sum_
mov ah,4ch ; 功能:结束程序,返回DOS系统
int 21h ; DOS功能调用
sum_ proc near
mov cx,4
clc
again:
mov al,[si]
adc al,[di]
daa
mov [bx],al
inc si
inc di
inc bx
loop again
ret
sum_ endp
code ends
end start
- 从键盘输入两个8位十进制整数,并采用压缩的BCD码保存在NUM1和NUM2中,然后把它们求和并保存在SUM中,最后把SUM的内容显示出来。
;sum2.asm
data segment
num1 db 4 dup(?)
num2 db 4 dup(?)
sum db 4 dup(?)
data ends
code segment
assume cs:code, ds:data
start:
mov ax,data
mov ds, ax
lea bx,num1
add bx,0003h
mov di,bx
call input_
mov ah,01h
int 21h
lea bx,num2
add bx,0003h
mov di,bx
call input_
lea bx,num1
mov si,bx
inc di
lea bx,sum
call sum_
dec bx
mov si,bx
mov bl,10h
mov ah,01h
int 21h
call output_ ; DOS功能调用
mov ah,4ch ; 功能:结束程序,返回DOS系统
int 21h ; DOS功能调用
input_ proc near
mov cx,4
do_input:
mov ah,01h
int 21h
sub al,30h
mov bx,cx
mov cl,4
shl al,cl
mov cx,bx
mov [di],al
mov ah,01h
int 21h
sub al,30h
add [di],al
dec di
loop do_input
ret
input_ endp
sum_ proc near
mov cx,4
clc
again:
mov al,[si]
adc al,[di]
daa
mov [bx],al
inc si
inc di
inc bx
loop again
ret
sum_ endp
output_ proc near
mov cx,4
output:
mov ax,0000h
mov al,[si]
div bl
add al,30h
mov dl, al
mov bh,ah
mov ah,02h ; 功能:显示输出
int 21h
mov ah,bh
add ah,30h
mov dl, ah
mov ah,02h ; 功能:显示输出
int 21h
dec si
loop output
ret
output_ endp
code ends
end start
- 采用压缩的BCD码完成任意30位以内的十进制整数加法,要求从键盘输入任意两个整数(长度可以不同)NUM1和NUM2、然后求和并保存在SUM中、最后把SUM的内容显示出来。
;sum3.asm
data segment
num1 db 15 dup(?)
num2 db 15 dup(?)
sum db 15 dup(?)
dre dw 1 dup(?)
data ends
code segment
assume cs:code, ds:data
start:
mov ax,data
mov ds, ax
mov dl,0
lea bx,num1
mov di,bx
call push_
mov dh,dl
mov dl,0
lea bx,num2
mov di,bx
call push_
lea bx,num1
mov si,bx
lea bx,num2
mov di,bx
lea bx,sum
cmp dh,dl
jl else_
mov dl,dh
else_:
mov cl,dl
call sum_
mov al,0
adc al,al
daa
mov [bx],al
lea bx,sum
add bx,14
mov si,bx
mov bl,10h
call output_ ; DOS功能调用
mov ah,4ch ; 功能:结束程序,返回DOS系统
int 21h ; DOS功能调用
push_ proc near
pop si
mov ax,0000h
push ax
mov cx,30
do_push:
mov ah,01h
int 21h
cmp al,30h
jl over_
sub al,30h
mov ah,00h
push ax
inc dl
loop do_push
over_:
mov ah,00h
mov al,2
mov bl,al
mov al,dl
div bl
mov ch,00h
mov cl,al
add cl,ah
mov dl,cl
call pop_
lea bx,dre
mov si,[bx]
push si
ret
push_ endp
pop_ proc near
lea bx,dre
mov [bx],si
pop si;pop_函数返回地址出栈
do_pop:
pop ax
mov [di],al
pop ax
mov bl,cl
mov cl,4
shl al,cl
mov cl,bl
add [di],al
inc di
loop do_pop
push si;pop_函数返回地址入栈
ret
pop_ endp
sum_ proc near
clc
again:
mov al,[si]
adc al,[di]
daa
mov [bx],al
inc si
inc di
inc bx
loop again
ret
sum_ endp
output_ proc near
mov cx,15
output:
mov ax,0000h
mov al,[si]
div bl
add al,30h
mov dl, al
mov bh,ah
mov ah,02h ; 功能:显示输出
int 21h
mov ah,bh
add ah,30h
mov dl, ah
mov ah,02h ; 功能:显示输出
int 21h
dec si
loop output
ret
output_ endp
code ends
end start
实验过程中遇到的问题
- 用masm5.0编译汇编语言,出现unable to open input file:
查了许多相关问题,最常见回答是masm5.0不支持长文件名,要把源程序文件名改为8.3格式(文件名不超过8个字符,拓展名不超过3个字符)。然而这个答案没有解救我23333……最后把源程序放到了masm5文件夹里,问题解决了😄 - Debug 时输入u不能显示源代码,程序陷入死循环,加上.exe拓展名后解决。要注意文件名书写完整。
- 在函数中使用push和pop,函数返回时跳转到错误的地方,将函数返回地址存储在si寄存器和地址变量内后解决。调用函数时会把返回地址入栈,要注意保护返回地址