实验9 根据材料编程

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

补全得t1。asm如下:

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

在此代码段中,div指令使al/10,除数为八位,al存储除法操作的商,ah存储除法操作的余数,倘如为16位,ax,则存储商,dx存储余数。

mov ah,2  为二号功能调用,输出dl内的字符格式内容

add dl,30h 意为把dl内容数字字符画,数字与数字字符ASCII码值间相差48,即30h

成功编译连接:

可得如下结果,成功输出“12”:

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

补全得t2.asm,如下:

 1 assume cs:code, ds:data
 2 data segment
 3      db 12,35,96,55,67
 4 data ends
 5 code segment
 6 start:
 7       mov ax,data; 补全程序,参考t1.asm,综合应用以下知识完成:
 8       mov ds,ax  
 9       mov si,0
10       mov cx,0005
11       
12    s: mov ah,0
13       mov al,ds:[si] 
14       mov bl,10
15       div bl
16 
19       mov bh,ah   
20 
21       mov ah,2
22       mov dl,al
23       add dl,30h
24       int 21h
25 
26       ;mov ah,2
27       mov dl,bh  
28       add dl,30h        
29       int 21h
30       
31       ;mov ah,2
32       mov dl,32
33       int 21h
34       add si,1;
35       loop s
36       
37       ; (1) loop指令、内存单元地址的灵活表示
38       ; (2) div指令, 数字→数字字符的转换
39       ; (3) int 21h的2号子功能,完成单个字符输出的方法,即: 
40       ;     mov ah,2
41       ;     mov dl,待输出字符或其ASCⅡ码
42       ;     int 21h
43       ; (4) 数据和数据之间以空格间隔的实现: 使用(3)输出空格字符
44       
45       mov ax,4c00h
46       int 21h
47 code ends
48 end start

原理同任务1,关于al和ah的数值移动,al保留,因为其它内容不曾动用ax的低八位寄存器,故可直接赋给dl,

ah中的数值则间接通过bh传至dl;

空格则直接赋予dl=32,对应空格字符

成功编译连接:

可得如下结果,成功输出数字字符串:

3.编程:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串‘welcome to masm!'

编写代码如下:

 1 ; p187 实验9
 2 
 3 assume ds:data, cs:code
 4 data segment
 5        db 'welcome to masm!'  
 6        db 2H,24H,71H          ;字符串属性值
 7 data ends
 8 
 9 code segment
10 start:  mov ax,data
11         mov ds,ax            ;字符串及属性值所在段的段地址送入ds
12         
13         mov ax,0b800H
14         mov es,ax            ;80×25彩色字符模式显示缓冲区段地址送入es
15         
16         mov di,0
17         mov bx,1820
18         
19         mov cx,3
20         
21      s: push cx
22         mov si,0
23         mov cx,16
24     s0: mov al,ds:[si]
25         mov es:[bx],al
26         
27         mov al,ds:[16+di]
28         mov es:[bx+1],al
29         
30         inc si
31         add bx,2
32         loop s0
33         
34         add di,1
35         add bx,128
36         pop cx
37         loop s
38         ; 添加代码,通过循环逐个将每个字符及其属性送入相应的显示缓冲区对应行
39         ; 即:将data段的字符及属性通过循环逐个mov到显示缓冲区(es)段相应的单元内
40         
41         ; 可以先尝试分别写三段代码,每次完成一行的显示
42         ; 程序运行起来后,再尝试通过灵活的寻址方式和循环,对三段代码修改和简化
43         ; 学习第10章子程序后,还可以进一步完善优化,设计子程序,将行号、列号、颜色属性设置成入口参数
44         
45 
46         mov ax,4c00h
47         int 21h
48 code ends
49 end start

代码段中的显示缓冲区位于B800H~BFFFFH共32KB的空间中,缓冲区分为25行,80列,代码段中使用b800h为段地址,经过不断调试与磨合,本人选区以偏移地址为1820(十进制)开始的区域写入字符内容和属性值,因为每行相差160个字节内容,而字符串为16个字节,又结合属性值,总共占有16*2个字节,故本人通过add bx,160-16*2来换行对齐。

该代码段使用双重循环,共执行3*16次。

成功编译连接:

可成功得如下执行结果:

本次实验循序渐近,任务内容难度逐渐提高,但本质上大同小异,会做任务1,通过自我探索,不难实现任务2、3。

posted @ 2018-12-08 18:19  但愿人长久的路小周  阅读(166)  评论(0编辑  收藏  举报