计组实验学习记录(二)

8086汇编(二)

实验内容

  1. 把一组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
  1. 对数据(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

实验过程中遇到的问题

  1. 用pop取到了奇怪的数据,检查代码使push和pop像括号一样成对对称出现后解决。要注意数据入栈出栈的顺序。
  2. mov [dx],al出现错误。修改如下解决:
    push bx
    mov bx,dx
    mov [bx],al
    pop bx
    

要注意不同数据寄存器间的区别

  1. cmp [bx],[si]出现错误;mov [bx],[si]出现错误。修改如下解决:
    mov dh,[si]
    mov dl,[bx]
    cmp dl,dh
    jl else_3
    mov [bx],dh
    

不能直接通过si和bx中存储的地址直接读取内存并比较或赋值。

  1. 用cmp比较A0h和09h,后接jl跳转,结果竟然发生跳转,把jl改为jb后解决。Jl是有符号小于跳转,jb是无符号小于跳转,要注意指令作用条件的细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值