• 汇编——实验9


    一.实验内容及结论

    (一)实验任务一

    补全程序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的操作,对于之前感到很神奇的事情有了合理的解释,收获了许多。

  • 相关阅读:
    spring学习笔记---数据库事务并发与锁详解
    VIM
    Linux命令总结(转)
    js实现配置菜品规格时,向后台传一个json格式字符串
    js 子窗口调用父框框方法
    springMVC 的拦截器理解
    java 使用poi 导入Excel 数据到数据库
    导入jeesite 项目
    JS动态添加删除html
    在Linux CentOS 下安装JDK 1.8
  • 原文地址:https://www.cnblogs.com/zjybel/p/10075795.html
Copyright © 2020-2023  润新知