• 实验九 根据材料编程


    练习1:

      在屏幕上输出内存单元中的十进制两位数。

     1 ; 在屏幕上输出内存单元中的十进制两位数
     2 assume cs:code, ds:data
     3 data segment
     4      db 12
     5      db 0,0   ; 前一个字节用于保存商,后一个字节用于保存余数
     6 data ends
     7 code segment
     8 start:
     9       mov ax,data
    10       mov ds,ax        ; 补全指令,使得ds <-- data段地址
    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
    View Code

      现在所学,只能输出当个字符。

    1 mov ah,2
    2 mov dl,30H
    3 int 21h

      dl是要输出的数值。

      现在的想法是一位一位输出,先通过除十,商为十位上的值,余数为个位数上的值。

      附除法(div)使用方法:

        (1)除数:有8位或者16位两位,在一个reg或内存单元中。

        (2)被除数:默认放在AX或者DX中,如果除数为8位,被除数则为16位,默认在AX中存放;如果除数为16位,被除数则为32位,在DX和AX中存放,DX存放高16位,AX存放低16位。

        (3)结果:如果除数为8位,则AL存储除法操作的商,AH存储除法操作的余数;如果除数为16位,则AX存储除法操作的商,DX存储除法操作的余数。

    练习2:

      在屏幕上输出data段定义的5个十进制两位数,数据和数据之间以空格间隔。 

     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
     8       mov ds,ax
     9       mov cx,5
    10       mov bx,0
    11 s:    mov ax,0
    12       mov dl,10
    13       mov al,[bx]
    14       div dl
    15       mov dl,al
    16       mov dh,ah
    17 
    18       mov ah,2
    19       add dl,30H
    20       int 21H
    21 
    22       mov ah,2
    23       mov dl,dh
    24       add dl,30H
    25       int 21H
    26 
    27       mov ah,2
    28       mov dl,20H
    29       int 21H 
    30       inc bx
    31       loop s
    32       
    33       mov ax,4c00h
    34       int 21h
    35 code ends
    36 end start
    View Code

      思路同第一问,先将data作为段地址,之后将数据读入al中,用除法,取每一位的个数,输出。

      空格的ASCII码为20H。

      

     练习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 code segment
     9 start:  mov ax,data
    10         mov ds,ax            ;字符串及属性值所在段的段地址送入ds
    11         mov ax,0b800H
    12         mov es,ax            ;80×25彩色字符模式显示缓冲区段地址送入es
    13         mov si,06E0H      ;es的偏移地址
    14         mov bx,0             ;属性值的偏移地址
    15         mov cx,3
    16 
    17 k:     mov dh,cl
    18         mov cx,16
    19         mov di,0
    20 z:      mov al,ds:[di]
    21         mov es:[si],al
    22         inc si
    23         mov al,ds:[bx+16]
    24         mov es:[si],al 
    25         inc di
    26         inc si
    27         loop z
    28 
    29         inc bx
    30         mov cl,dh
    31         add si,0080H
    32         loop k
    33 
    34         mov ax,4c00h
    35         int 21h
    36 code ends
    37 end start
    View Code

      

      里面用了两重循环,第一层循环为3,第二层循环为16。loop用执行的时候当且仅当判断CX的值,所以我们可以先藏起来。偷偷地赋给BH值,再给CX赋第二层循环的次数,第二层循环完了,BH再找回并把CX的初值交给CX,并执行loop。(感觉自己可以去一篇小说了。。。)如果想要n重循环(n>2),建议创建栈空间,分别利用PUSH,POP实行上述操作。因为寄存器个数有限。需要合理运用。且行且珍惜。AX不断重写数据,CX判断循环,不能乱放数据。一下子少了两个能用的寄存器,所以正常能用也就是BX和DX了。。

      中间的行数是11,12,13行

        

      注意:其中换行,应该si+80H,而不是A0H,是因为第一次循环结束时,si=06E0H+20H=0700H,再加A0H,就变成了07A0H,而第二次开始的si应该是0780H,其中多加商第一次循环所的20H。

      全屏输出: 

     1 assume ds:data, cs:code
     2 data segment
     3        db 'Welcome to masm!'  
     4        db 2H,24H,71H          ;字符串属性值
     5 data ends
     6 code segment
     7 start:  mov ax,data
     8         mov ds,ax            ;字符串及属性值所在段的段地址送入ds
     9         mov ax,0b800H
    10         mov es,ax            ;80×25彩色字符模式显示缓冲区段地址送入es
    11         mov si,0              ;es的偏移地址
    12         mov bx,0             ;属性值的偏移地址
    13         mov cx,125
    14 
    15 k:     mov dh,cl
    16         mov cx,16
    17         mov di,0
    18 z:      mov al,ds:[di]
    19         mov es:[si],al
    20         inc si
    21         mov al,ds:[bx+16]
    22         mov es:[si],al 
    23         inc di
    24         inc si
    25         loop z
    26 
    27         inc bx
    28         mov ax,bx
    29         mov bx,3
    30         div bl
    31         mov bl,ah
    32         mov cl,dh
    33         loop k
    34 
    35         mov ax,4c00h
    36         int 21h
    37 code ends
    38 end start
    View Code

      其中比较重要的一个,就是多加一个bx取3的余数。

      运行结果:

       

     实验总结与感受

      1.输出方法,单个字符输出。其中dl是ASCII码。

        mov ah,2 

        mov dl,al

        int 21h

      2.第种输出方法是向B8000H-BFFFFH显示缓冲区,偶地址放入字符的ASCII码,奇地址存放字符的颜色属性。显示屏可以显示25行,每行80个字符,即B8000H~B8F9FH。

       颜色属性:R:红色      G:绿色       B:蓝色

      7 6 5 4 3 2 1 0
    含义 BL R G B I R G B
      闪烁 背景 高亮 前景

      

      3.关于多重循环,loop只能判断CX的值,要多重循环时,就必须先把CX的值,藏起来,再给CX重新赋值。这个过程可以用栈来执行。如果循环次数少,则用寄存器来存。

  • 相关阅读:
    堆栈、堆、方法区介绍
    spring 定时器
    fastJSON 使用总结
    [Python]collections.defaultdict()模块使用
    LeetCode 18.四数之和
    [Python]调用shell cmd的几种方式
    LeetCode 16. 最接近的三数之和
    Objective C 十六进制 十进制互转
    LeetCode 15. 三数之和
    要做的题
  • 原文地址:https://www.cnblogs.com/auspice/p/10059519.html
Copyright © 2020-2023  润新知