一.实验内容及结论

(一)实验任务一

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

源程序:

; 在屏幕上输出内存单元中的十进制两位数
assume cs:code, ds:data
data segment
     db 12
     db 0,0   ; 前一个字节用于保存商,后一个字节用于保存余数
data ends
code segment
start:
      mov ax,data       ; 使得ds <-- data段地址
      mov ds,ax
      
      mov ah,0
      mov al,ds:[0]   ; ax <-- data段字节单元的被除数12
      mov bl,10
      div bl
      mov  ds:[1],al    ; 让商保存到data段注释中指定的单元
      mov  ds:[2],ah    ; 让余数保存到data段注释中指定的单元

      mov ah,2
      mov dl,ds:[1]    ; 使得dl <-- data段中保存的商的字节单元数值
      add dl,30h      ; 使得dl中的数值转换为数字字符
      int 21h
      
      mov ah,2
      mov dl,ds:[2]     ; 使得dl <-- data段中保存余数的字节单元数值
      add dl,30h        ; 使得dl中的数值转换为数字字符      
      int 21h

      mov ax,4c00h
      int 21h
code ends
end start

运行结果:

 

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

源程序:

assume cs:code, ds:data,ss:stack
data segment
     db 12,35,96,55,67  ;0 1 2 3 4
     dw 0 ;5 6 
data ends

stack segment
     dw 8 dup(0) 
stack ends

code segment
start:
      mov ax,data
      mov ds,ax
      mov ax,stack
      mov ss,ax
      mov sp,10h
      
      mov cx,5
      mov bx,0
s:    mov si,5
      mov ah,0
      mov al,ds:[bx]
      mov dl,10
      div dl ;作除法
      
      mov ds:[si],al ;
      mov ds:[si+1],ah ;余数
      push cx   ;将第一层循环次数(cx)入栈,开始第二层循环
      mov cx,2
      
s0:   mov ah,2  ;输出商和余数
      mov dl,ds:[si]
      add dl,30h
      int 21h
      inc si 
      loop s0
     
      mov ah,2  ;输出空格
      mov dl,0
      int 21h
      inc bx
      pop cx
      loop s
      
      mov ax,4c00h
      int 21h
code ends
end start

运行结果:

 

(三)教材实验9,在屏幕中央分别显示绿色、绿底红色、白底蓝色的字符串'welcome to masm!'。

源程序:

; p187 实验9

assume ds:data, cs:code,ss:stack
data segment
       db 'welcome to masm!'  ;0-15
       db 2H,24H,71H          ;字符串属性值 16 17 18
data ends

stack segment
       dw 8 dup(0) 
stack ends

code segment
start:  mov ax,data
        mov ds,ax            ;字符串及属性值所在段的段地址送入ds
        mov ax,stack
        mov ss,ax
        mov sp,10h
        
        mov ax,0b800H
        mov es,ax            ;80×25彩色字符模式显示缓冲区段地址送入es
        
        mov di,16
        mov si,06e0h
        mov cx,3
s0:     push cx
        mov cx,16
        mov bx,0
        
s1:     mov al,ds:[bx]  ;字符
        mov ah,ds:[di]  ;属性
        mov es:[si],al
        mov es:[si+1],ah
        inc bx  ;依次后移字符
        add si,2  ;依次后移在屏幕中输出的位置
        loop s1
        
        pop cx
        inc di  ;改变属性
        add si,80h  ;换行
        loop s0

        mov ax,4c00h
        int 21h
code ends
end start

运行结果:

 

二、总结与体会

虽说这3个实验只是简单地按照相应要求在屏幕上输出相应的字符数据等。但是当自己独立将它们都做出来后,还是成就感满满的。

1.首先第一个和第二个实验中,都运用到了无符号除法div指令和在屏幕上输出相关字符的固定代码(如下)。

assume cs:code
code segment
            ...
            mov ah,2
            mov dl,'A'  ;将想要输出的字符(或其ASCII码)送入dl寄存器中
            int 21h
            ...
    
            mov ax,4c00h
            int 21h
code ends
        

同时由于实际需要(可能需要用ax寄存器完成其他相关操作),需要将商和余数分别从al,ah寄存器中送入内存单元中保存,这就涉及到了内存单元和寄存器的相关转换,在循环中需要注意其相应的偏移地址的改变是否一一对应。如实验任务2中,需要将5个十进制两位数在屏幕上显示出来,在这里我的处理是每次用div指令算出相应十进制数的商和余数后,将其送入内存单元中,以便后面的输出,在这里,存放这5个数的商和余数的内存单元地址不变,每次都用新的值去覆盖它,再将其送入dl寄存器中在屏幕上输出。

2.当要把一个数在屏幕上输出时,由于我们还没有学到可以将数字完整输出在屏幕上的指令,所以只能按照上述固定模式按个将字符输出。在这里就要用到高级语言中的数位分离的思想,把每一位上的数单独拿出来输出。只需要将该数连续除以10取余,直至商为0为止,在这过程中所得的余数即为该数每一位上的数字的反序排列。再利用循环将其输出。

3.通过完成实验任务3,我更加深入地理解到了80*25彩色字符模式显示缓冲区的相关知识。对之前做的实验有了进一步的了解。实验任务3中需要解决

①如何在屏幕中间输出相应字符 ②如何显示绿色、绿地红色、白底蓝色的字符串。

通过老师对该实验的补充和实验提示,我对其有了相应的了解。

对于问题①,

<1>总的来说,80*25彩色字符模式显示缓冲区早内存地址空间中为B8000H-BFFFFH共32KB的空间。显示缓冲区分为8页,一页4KB,显示器可以显示任意一页的内容,一般情况下显示第0页的内容。

<2>对于每个字符而言,一个字符占两个字节,分别存放字符的ASCII码和属性,每个字符有256种属性。显示器可以显示25行,每行80个字符即160个字节。故而在80*25模式下,一页的内容在显示缓冲区中共占2000个字符即4000个字节。

由图可得:屏幕中间的位置在Line11,12,13处,即要在屏幕中央输出字符只需在内存单元地址为B800:06E0H~B800:08BFH处写入相应字符信息。

对于问题②,

<1> 一个字符占两个字节,低位字节(偶地址)存储字符的ASCII码,高位字节(奇地址)存储字符的属性。由此可知,对于输出字符的颜色要求主要与属性字节有关。

属性字节的格式:

            7    6  5  4  3 2 1  0

含义: BL  R G B  I  R G B

           闪烁  背景 高亮  前景

(R,G,B分别表示red,green,blue。)

可以通过按位设置属性字节,从而配出各种不同的前景色和背景色。

例如,常用的几种颜色如下:

 

 

 

 

 

 

解决了①②的问题后就可以比较顺利地把任务3完成啦。

总的来说,每次实验都是对知识的巩固和拓展,之前对div指令并不是很熟悉,只是觉得它存放商和余数的寄存器很绕,但是通过实验9的上机操作,对如何使用div指令,商和余数的存放都有了很深的印象。通过实验任务3的操作,对于之前感到很神奇的事情有了合理的解释,收获了许多。

 

 posted on 2018-12-06 19:08  G_fish  阅读(185)  评论(0编辑  收藏  举报