实验九:根据材料编程

实验任务一

 要求:补全程序 t1.asm,完成在屏幕上输出内存单元中的十进制两位数。

 1 ;t1.asm
 2 ; 在屏幕上输出内存单元中的十进制两位数
 3 assume cs:code, ds:data
 4 data segment
 5      db 12
 6      db ?,?   ; 前一个字节用于保存商,后一个字节用于保存余数
 7 data ends
 8 code segment
 9 start:
10       ××××
11       ××××        ; 补全指令,使得ds <-- data段地址
12 
13       mov ah,0
14       mov al,ds:[0]   ; ax <-- data段字节单元的被除数12
15       mov bl,10
16       div bl
17       mov  ××,al    ; 补全代码,让商保存到data段注释中指定的单元
18       mov  ××,ah    ; 补全代码,让余数保存到data段注释中指定的单元
19 
20       mov ah,2
21       mov dl,××    ; 补全代码,使得dl <-- data段中保存的商的字节单元数值
22       ××××       ; 补全代码,使得dl中的数值转换为数字字符
23       int 21h
24 
25       mov ah,2
26       mov dl,××     ; 补全代码,使得dl <-- data段中保存余数的字节单元数值
27       ××××        ; 补全代码,使得dl中的数值转换为数字字符      
28       int 21h
29 
30       mov ax,4c00h
31       int 21h
32 code ends
33 end start

补充好的代码为:

运行结果:

小结:

此题要求输出一个十进制两位数,以目前所学知识还不能一次性打印2个甚至多个字符,只能一个一个的分别获取该数字的个位和十位,然后依据ASCLL码转换为对应的字符进行输出。而关键就在于如何获取个位和十位数字,这里我们采用了除法(div)指令来达到这个目的。

让10除两位数,得到的商即是该两位数的十位数字,得到的余数即是该两位数的个位数字。

实验任务二

要求:补全程序 t2.asm,完成在屏幕上输出 data 段定义的 5 个十进制两位数,数据和数据之间以空格间隔。

 1 ;t2.asm
 2 assume cs:code, ds:data
 3 data segment
 4      db 12,35,96,55,67
 5 data ends
 6 code segment
 7 start:
 8       ; 补全程序,参考t1.asm,综合应用以下知识完成:
 9       ; (1) loop指令、内存单元地址的灵活表示
10       ; (2) div指令, 数字→数字字符的转换
11       ; (3) int 21h的2号子功能,完成单个字符输出的方法,即: 
12       ;     mov ah,2
13       ;     mov dl,待输出字符或其ASCⅡ码
14       ;     int 21h
15       ; (4) 数据和数据之间以空格间隔的实现: 使用(3)输出空格字符
16       
17       mov ax,4c00h
18       int 21h
19 code ends
20 end start

补充好的代码为:

运行结果:

小结:

此题可认为是任务一的进阶,需要输出的数字更多了,并且增加了输出空格的要求。不过也不困难,设计一个单层循环即可解决。

实验任务三

要求:根据材料编程,在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串“welcome to masm!”。

材料(摘要):

  


编写好的代码为:

 

运行结果:

 小结:

 此题做出来也许并不难,难的是追求以一种更简洁的方式来完成任务。这是我目前想到的比较简洁的方法,采用了两层嵌套循环。

大体思路:

外层循环是bx在不同行之间切换,内层循环是si在指定行的某一位置开始依次移动并输出相应字符。

遇到的困难:

为了把data段的字符传送到显存中,还需要一个指针在这些字符间移动来传递字符,初期想让si身兼两职,让si也来充当这个角色,但是发现,显存中是用2个字节来表示一个字符的,即显存中的指针是递增2的,而data段中的指针只需要递增1,两者不兼容,所以。。。si还是专心当好它显存指针的职能吧,我另找了di来作为data段的指针。可是问题又来了,虽然字符传送的问题是解决了,但是每行字符的属性都不一样,我似乎还需要一个指针在这些属性值间游走来传递属性值,可是已经没有额外的指针寄存器可用了。为了最大化利用已有的指针寄存器,只能从寻找规律入手了。发现控制外层循环次数的cx是递减1的,而我们需要的属性值指针是递增1的,二者的和应当不变。于是便有了上面的解法。我还是采用di寄存器,因为一行字符的属性是一样的,可以在内层循环开始之前就将这一行的属性值设置好,这样在进入内循环的时候di也就被空了出来。

猜你喜欢

转载自www.cnblogs.com/kevin234/p/10088200.html