8086汇编(二)
实验内容
- 把一组8位二进制数(无符号数)转换为十进制数并显示出来
;msort.asm
data segment
nums1 db 100,34,78,9,160,200,90,65
data ends
code segment
assume cs:code
start:
mov ax,data
mov ds,ax
mov es,ax
mov bx,offset nums1
mov cx,8
again:
call showdecs
mov dl,0ah
mov ah,02h
int 21h
loop again
mov ah,4ch ; 功能:返回DOS系统
int 21h ; DOS功能调用
; 把一组十六进制数据转换为十进制数并显示出来
; 参数:ds:bx --基地址 cx -- 数据个数
showdecs proc near
mov al,[bx]
mov ah,00h
call showdec
inc bx
ret
showdecs endp
;把al中的二进制数转换为十进制数并显示出来。
showdec proc near
push ax
push bx
push cx
push dx
mov cx,2
do_:
mov bl,0ah
div bl
mov bh,al
mov al,ah
mov ah,00h
push ax
mov al,bh
loop do_
add al,30h
mov dl, al
mov ah,02h ; 功能:显示输出
int 21h
mov ah,00h
pop ax
add al,30h
mov dl, al
mov ah,02h ; 功能:显示输出
int 21h
mov ah,00h
pop ax
add al,30h
mov dl, al
mov ah,02h ; 功能:显示输出
int 21h
pop dx
pop cx
pop bx
pop ax
ret
showdec endp
code ends
end start
- 对数据(2^n个整数)进行归并排序,最后把排序结果SUM显示出来。要求采用递归的方法(在子程序中调用自己)实现。
;msort.asm
data segment
nums1 db 100,34,78,9,160,200,90,65
nums2 db 212,152,8,49,83,35,79,51
buffer db 8 dup(?) ; 用于两个有序数列进行合并的缓冲区
bufptr dw 0 ; buffer中已合并数据的个数
data ends
code segment
assume cs:code
start:
mov ax,data
mov ds,ax
mov es,ax
;对nums1中的数据排序并显示
mov bx,offset nums1
mov cx,8
call mergesort
mov bx,offset nums1
mov cx,8
again:
call showdecs
mov dl,0ah
mov ah,02h
int 21h
loop again
;显示换行和回车
mov dl,0ah
mov ah, 02h
int 21h
mov dl,0dh
mov ah, 02h
int 21h
;对nums2中的数据排序并显示
mov bx,offset nums2
mov cx,8
call mergesort
mov bx,offset nums2
mov cx,8
again_1:
call showdecs
mov dl,0ah
mov ah,02h
int 21h
loop again_1
mov ah,4ch ; 功能:返回DOS系统
int 21h ; DOS功能调用
; 对一组数据进行归并排序(采用递归方法实现)
; bx--基地址 addr cx--数据个数
mergesort proc near
cmp cx,2
jl else_1
push cx
mov ax,cx
push bx
mov bl,02
div bl
mov cx,ax
pop bx
push bx
call mergesort
add bx,cx
call mergesort
pop bx
call mergepart
pop cx
push cx
push bx
lea dx,buffer
back_1:
call copyFromBufferToNums
loop back_1
pop bx
pop cx
else_1:
ret
mergesort endp
; 对两组已分别排序的数据进行合并和排序,两组数据的个数相同
; 中间结果可以存放到buffer中,最后结果要放到原区域
; 参数:bx--基地址(两部分连续存放),cx--每组数据的个数
mergepart proc near
push bx
lea dx,buffer
mov si,bx
add bx,cx
push cx
mov al,cl
mov ah,cl
mov cx,8
part:
push cx
mov cx,dx
mov dh,00h
mov dl,[bx]
push dx
push ax
mov dh,[si]
mov dl,[bx]
cmp dl,dh
jb else_3
mov [bx],dh
dec al
inc si
else_3:
push ax
mov al,[bx]
mov dx,cx
call saveToBuffer
mov cx,dx
pop ax
pop dx
cmp al,dl
jb else_4
dec ah
else_4:
mov ch,dl
pop dx
mov [bx],dl
mov dl,ch
mov ch,00h
cmp al,dl
jb else_9
inc bx
else_9:
mov dx,cx
pop cx
cmp al,1
jb else_2
cmp ah,1
jb else_5
loop part
else_2:
mov al,ah
mov ah,00h
mov cx,ax
do_bx:
mov al,[bx]
call saveToBuffer
inc bx
loop do_bx
pop cx
pop bx
ret
else_5:
mov cx,ax
do_si:
mov al,[si]
call saveToBuffer
inc si
loop do_si
pop cx
pop bx
ret
mergepart endp
; 把buffer中的数据拷贝到bx开始的存储区中
; 参数:bx--基地址,cx--数据个数
copyFromBufferToNums proc
push si
push ax
mov si,dx
mov al,[si]
mov [bx],al
pop ax
pop si
inc dx
inc bx
ret
copyFromBufferToNums endp
; 把al的数据保存到buffer中
saveToBuffer proc
push bx
mov bx,dx
mov [bx],al
pop bx
inc dx
ret
saveToBuffer endp
; 把一组十六进制数据转换为十进制数并显示出来
; 参数:ds:bx --基地址 cx -- 数据个数
showdecs proc near
mov al,[bx]
mov ah,00h
call showdec
inc bx
ret
showdecs endp
;把al中的二进制数转换为十进制数并显示出来。
showdec proc near
push ax
push bx
push cx
push dx
mov cx,2
do_:
mov bl,0ah
div bl
mov bh,al
mov al,ah
mov ah,00h
push ax
mov al,bh
loop do_
add al,30h
mov dl, al
mov ah,02h ; 功能:显示输出
int 21h
mov ah,00h
pop ax
add al,30h
mov dl, al
mov ah,02h ; 功能:显示输出
int 21h
mov ah,00h
pop ax
add al,30h
mov dl, al
mov ah,02h ; 功能:显示输出
int 21h
pop dx
pop cx
pop bx
pop ax
ret
showdec endp
code ends
end start
实验过程中遇到的问题
- 用pop取到了奇怪的数据,检查代码使push和pop像括号一样成对对称出现后解决。要注意数据入栈出栈的顺序。
mov [dx],al
出现错误。修改如下解决:push bx mov bx,dx mov [bx],al pop bx
要注意不同数据寄存器间的区别
cmp [bx],[si]
出现错误;mov [bx],[si]
出现错误。修改如下解决:mov dh,[si] mov dl,[bx] cmp dl,dh jl else_3 mov [bx],dh
不能直接通过si和bx中存储的地址直接读取内存并比较或赋值。
- 用cmp比较A0h和09h,后接jl跳转,结果竟然发生跳转,把jl改为jb后解决。Jl是有符号小于跳转,jb是无符号小于跳转,要注意指令作用条件的细节。