实验10 编写子程序 1.显示字符串

assume cs:code,ds:data

data segment
        db 'Welcome to masm!',0
data ends

code segment
start:  mov dh,8 ;dh表示行号(范围:1~25)
        mov dl,3 ;dl表示列号(范围:1~80)[注:每超过80等于行号自动加1]
        mov cl,2 ;cl中存放颜色属性(0cah为红底高亮闪烁绿色属性)
        mov ax,data
        mov ds,ax
        mov si,0
        call show_str

        mov ax,4c00h
        int 21h

show_str: ;显示字符串的子程序[定义开始]
        push cx ;cx和si寄存器后面会用到,防止值被覆盖,先入栈保存
        push si

        mov al,0a0h ;每行有 80*2 == 160个字节 == 0a0h个字节
                    ;al也就是表示每行有多少个字符

        dec dh ;行号在显存中下标从0开始,所以减1。因为计算机内部编号从0开始
        mul dh ;dh存放的是行数,dh*al相当于 (n-1)*0a0h。表示从
               ;第(n-1)*0a0h个Byte单元开始...
               ;(n-1)*0a0h相乘的结果默认放入ax中

        mov bx,ax ;定位好的位置偏移地址存放在bx里(bx定位了行地址)

        mov al,2 ;每个字符占两个字节
        mul dl ;dl存放列数,定位列,结果ax存放的是定位好的列的位置
        sub ax,2 ;列号在显存中下标从0开始,又因为偶字节存放字符,所以减2

        add bx,ax ;此时bx中存放的是行与列号的偏移地址

        mov ax,0b800h ;显存开始的地址
        mov es,ax ;es中存放的是显存的第0页(共0~7页)的起始的段地址

        mov di,0 ;di指向显存的偏移地址。指向下一个要处理的字符的位置
        
        mov al,cl ;cl是存放颜色的参数,这时候al存放颜色了
                  ;因为cl下面要用来临时存放要处理的字符

        mov ch,0 ;下边cx存放的是每次准备处理的字符

s:      mov cl,ds:[si] ;ds:[si]指向“Welcome to masm!”,0
                       ;例如当si=0时,就是把字符W赋给cl。cl存的是W的ASCII码

        jcxz ok ;当cl的值为0的时候,cx == 0,则发生跳转,到ok处结束处理!

        mov es:[bx+di],cl ;偶地址存放字符
        mov es:[bx+di+1],al ;奇地址存放字符的颜色属性

        inc si ;si自增1,指向下一个将要处理的字符串中的字符

        add di,2 ;指向了下个字符。因为每个字符在显存中占两个字节
        jmp short s ;无条件跳转,jcxz是离开的关键跳

ok:     pop si
        pop cx

        ret ;显示字符串的子程序[定义结束]
code ends
end start

执行效果截图:

实验10 编写子程序 1.显示字符串_第1张图片

转载于:https://www.cnblogs.com/houhaibushihai/p/9696895.html

你可能感兴趣的:(实验10 编写子程序 1.显示字符串)