一、实验目的

  • 会利用条件转移指令循环和控制结构解决问题
  • 学用查表法解决问题

二、实验内容过程记录

任务1-求最大值

在BUFFER处给出了多个无符号数,请找出其中的最大值,放至MAX指定的存储单元中。
data  segment
buffer dw 35098, 17758, 54582, 61504, 46054, 58513, 4409, 7902, 14255
dw 40623, 47645, 15575, 51572, 18110, 26511, 14880, 5921, 31999
dw 2893, 21056, 16574, 147, 25532, 33336, 5251, 64269, 31514, 23670
dw 53335, 49581, 57895, 25689, 51697, 58198, 27548, 54151, 41373
dw 44382, 23511, 39326, 56955, 51911
max dw  ?
data  ends
已知标号为BUFFER的数组后直接就是标号为MAX的单元,数组中元素的个数由程序计算,不得人工数。给定的数据中,最大者为64269(FB0DH)。
 
报告内容:
源程序:

assume cs:codesg,ds:data
data  segment
  buffer dw 35098, 17758, 54582, 61504, 46054, 58513, 4409, 7902, 14255
         dw 40623, 47645, 15575, 51572, 18110, 26511, 14880, 5921, 31999
         dw 2893, 21056, 16574, 147, 25532, 33336, 5251, 64269, 31514, 23670
         dw 53335, 49581, 57895, 25689, 51697, 58198, 27548, 54151, 41373
         dw 44382, 23511, 39326, 56955, 51911
  max dw  ?
data  ends
codesg segment
start:
       mov ax,data
       mov ds,ax
       mov cx,offset max-offset buffer ;求出数据区占用的长度
       shr cx,1  ;每个数据占两个字节,右移一位,使其大小变为一半,求出数据的个数
       mov bx,0  ;作为最大值的暂存器,初始化为0
       mov si,0  ;变址地址的寄存器
    s: mov ax,buffer[si]  ;取数据
       cmp ax,bx   ;比较取出的数据
       jna next   ;若取出的数小于寄存器中的数,比较下一个数
       mov bx,ax  ;若取出的数大于寄存器中的数,将此数移入bx中
  next:inc si
        inc si
       loop s
 
       mov max,bx
 
       mov ax,4c00h
       int 21h
 
codesg ends
end start

运行结果:
assembly5-1

任务2-成绩统计
下面提供了100名同学AS课成的成绩,请编程序统计其中90~100、60~89、60以下者各有多少人?并把结果连续存放到自RESUT开始的单元中。
data segment
buf db 85, 72, 79, 90, 79, 54, 63, 66, 83, 79, 71, 77, 77, 65, 89, 93
db 69, 96, 72, 98, 60, 78, 69, 68, 80, 65, 91, 64, 90, 90, 64, 90
db 99, 55, 84, 56, 80, 54, 55, 66, 53, 54, 83, 61, 52, 92, 66, 51
db 95, 81, 51, 100, 70, 65, 50, 74, 91, 57, 95, 66, 54, 50, 73, 59
db 78, 80, 92, 78, 89, 78, 99, 100, 82, 92, 59, 71, 74, 81, 93, 74
db 98, 57, 57, 96, 76, 79, 57, 67, 52, 84, 87, 54, 67, 72, 59, 75
db 64, 89, 77, 80
resut db 3 dup(0)
data ends
 
报告内容:
源程序:

assume cs:codesg,ds:data
data segment
   buf db 85, 72, 79, 90, 79, 54, 63, 66, 83, 79, 71, 77, 77, 65, 89, 93
       db 69, 96, 72, 98, 60, 78, 69, 68, 80, 65, 91, 64, 90, 90, 64, 90
       db 99, 55, 84, 56, 80, 54, 55, 66, 53, 54, 83, 61, 52, 92, 66, 51
       db 95, 81, 51, 100, 70, 65, 50, 74, 91, 57, 95, 66, 54, 50, 73, 59
       db 78, 80, 92, 78, 89, 78, 99, 100, 82, 92, 59, 71, 74, 81, 93, 74
       db 98, 57, 57, 96, 76, 79, 57, 67, 52, 84, 87, 54, 67, 72, 59, 75
       db 64, 89, 77, 80
 resut db 3 dup(0)
data ends
 
codesg segment
start:mov ax,data
      mov ds,ax
      mov cx,100  ;循环100次
      mov si,0   ;初始化变址寄存器
       mov di,0  ;初始化变址寄存器
    s:
      mov al,buf[si] ;取数据
      cmp al,90    ;比较与90的大小
      jb w1      ;小于九十跳走
      inc resut[di] ;大于等于90第一个结果区增一
      jmp e    ;进入下一次循环
 
    w1:cmp al,60   ;比较与60的大小
       jb w2   ;小于六十跳走
      inc resut[di+1]  ;大于等于60第二个结果区增一
      jmp e
 
    w2: inc resut[di+2] ;小于60时执行
      e:inc si
      loop s
 
       mov ax,4c00h
       int 21h
 
codesg ends
end start

 

运行结果:
assembly5-2
 

任务3-构造菜单

读懂并运行菜单程序,然后

(1)用代码的直接定址表改写程序

(2)增加一个功能,菜单显示项为“   5. DEBUG”

(3)在报告中比较原程序与改写后程序的优劣。

报告内容:

  • 我改写的程序及运行结果是:

源程序:

assume cs:code, ss:stack
stack segment
     db 100H dup (?)
stack ends
code  segment
      org 100h
start:
      jmp beg 
menu  db 10,13,10,13,'           MENU          '
      db 10,13
      db 10,13,'           1. FILE'
      db 10,13,'           2. EDIT'
      db 10,13,'           3. COMPILE'
      db 10,13,'           4. RUN'
      db 10,13,'           5. DEBUG'
      db 10,13,'           0. QUIT'
      db 10,13
      db 10,13,'   please choose one of 0~4:','$'
 
beg:
      push cs
      pop ds     ;设置数据段
disp0:
      lea dx,menu ;DS:DX=待输出字符的地址
      mov ah,9
      int 21h     ;调用21h中断的第9号功能,显示以'$'结束的字符串
 
      mov ah,1
      int 21h     ;调用21h中断的第1号功能,从键盘读入字符,AL保存读入字符的ASCII码
 
choice:jmp short set  ;越过标号
 table dw exit,sub1,sub2,sub3,sub4,sub5 ;程序标号
   set:mov bl,al  ;将键盘的ASCII码值穿入bl
       mov bh,0
       sub bx,30h  ;ASCII码值减30h得到其对应十进制数字
       add bx,bx  ;将它的地址扩大一倍,得到在table表中的偏移
       call word ptr table[bx]  ;调用对应功能子程序
 
       jmp disp0
 
 
 
exit:
      mov ah,4ch
      int 21h
 
sub1  proc near
      jmp sub1_disp
      file db 10,13,'   --new, open, save, print files.---','$',10,13
sub1_disp:
      lea dx,file
      mov ah,9
      int 21h     ;调用21h中断的第9号功能,显示以'$'结束的字符串
      ret
sub1  endp
 
sub2  proc near
      jmp sub2_disp
      edit db 10,13,'   --copy, cut, paste the text.---','$',10,13
sub2_disp:
      lea dx,edit
      mov ah,9
      int 21h     ;调用21h中断的第9号功能,显示以'$'结束的字符串
      ret
sub2  endp
 
sub3  proc near
      jmp sub3_disp
      compile db 10,13,'   --compile the source file, then get target file.---','$',10,13
sub3_disp:
      lea dx,compile
      mov ah,9
      int 21h     ;调用21h中断的第9号功能,显示以'$'结束的字符串
      ret
sub3  endp
 
sub4  proc near
      jmp sub4_disp
      run db 10,13,'   --run, run, run, cannot stop.---','$',10,13
sub4_disp:
      lea dx,run
      mov ah,9
      int 21h     ;调用21h中断的第9号功能,显示以'$'结束的字符串
      ret
sub4  endp
sub5  proc near
      jmp sub5_disp
      debug db 10,13,'   --debug-','$',10,13
sub5_disp:
      lea dx,debug
      mov ah,9
      int 21h     ;调用21h中断的第9号功能,显示以'$'结束的字符串
      ret
sub5  endp
code  ends
      end start

 

运行结果:
assembly5-3
 

(2)原程序方案和改写后的方案相比:采用了程序的直接定址表的方法,用根据功能号查找地址的方法,程序的结构清晰,便于扩充。如果加入一个新的功能子程序,那么只需要在地址表中加入它的入口地址就好了。
 
三、实验总结
O(事实):本次实验的主要内容是条件转移与直接定址表。

R(感受): 直接定址表是一种高效简洁的寻址方式,方便程序拓展。

I(思考):利用直接定址表,可以更加方便的寻址,找到更优的解决方案。

D(决定):要深入理解程序的寻址方式,了解其寻址实现的细节。

 

附:任务3原始程序

assume cs:code, ss:stack
stack segment
     db 100H dup (?)
stack ends
code  segment
      org 100h
start:
      jmp beg
menu  db 10,13,10,13,'           MENU          '
      db 10,13
      db 10,13,'           1. FILE'
      db 10,13,'           2. EDIT'
      db 10,13,'           3. COMPILE'
      db 10,13,'           4. RUN'
      db 10,13,'           0. QUIT'
      db 10,13
      db 10,13,'   please choose one of 0~4:','$'
 
beg:
      push cs
      pop ds     ;设置数据段
disp0:
      lea dx,menu ;DS:DX=待输出字符的地址
      mov ah,9
      int 21h     ;调用21h中断的第9号功能,显示以'$'结束的字符串
 
      mov ah,1
      int 21h     ;调用21h中断的第1号功能,从键盘读入字符,AL保存读入字符的ASCII码
 
      cmp al,'0'
      je exit
      cmp al,'1'
      je disp1
      cmp al,'2'
      je disp2
      cmp al,'3'
      je disp3
      cmp al,'4'
      je disp4
      jmp disp0
disp1:
      call sub1
      jmp disp0
disp2:
      call sub2
      jmp disp0
disp3:
      call sub3
      jmp disp0
disp4:
      call sub4
      jmp disp0
 
exit:
      mov ah,4ch
      int 21h
 
sub1  proc near
      jmp sub1_disp
      file db 10,13,'   --new, open, save, print files.---','$',10,13
sub1_disp:
      lea dx,file
      mov ah,9
      int 21h     ;调用21h中断的第9号功能,显示以'$'结束的字符串
      ret
sub1  endp
 
sub2  proc near
      jmp sub2_disp
      edit db 10,13,'   --copy, cut, paste the text.---','$',10,13
sub2_disp:
      lea dx,edit
      mov ah,9
      int 21h     ;调用21h中断的第9号功能,显示以'$'结束的字符串
      ret
sub2  endp
 
sub3  proc near
      jmp sub3_disp
      compile db 10,13,'   --compile the source file, then get target file.---','$',10,13
sub3_disp:
      lea dx,compile
      mov ah,9
      int 21h     ;调用21h中断的第9号功能,显示以'$'结束的字符串
      ret
sub3  endp
 
sub4  proc near
      jmp sub4_disp
      run db 10,13,'   --run, run, run, cannot stop.---','$',10,13
sub4_disp:
      lea dx,run
      mov ah,9
      int 21h     ;调用21h中断的第9号功能,显示以'$'结束的字符串
      ret
sub4  endp
code  ends
      end start

 

点击此处下载实验报告:
  Download


人与人之间是平等的,自由的。