匯編語言 : 子程序設(shè)計 ( 在屏幕上指定位置顯示一個以 0 結(jié)尾的字符串 )


簡介 :

子程序描述 : 
    名稱 : show_str
    功能 : 在指定的位置顯示一個用 0 結(jié)束的字符串
    參數(shù) : (dh) = 行號 (0-24) , (dl) = 列號 (0-79)
    返回 : None

分析 :

根據(jù)之前的分析 , 我們已經(jīng)了解了顯存的范圍等等信息
也知道了只要往顯存中寫入數(shù)據(jù) , 就可以顯示到對應(yīng)的位置
我們這里需要做的一件事就是搞清楚顯存地址和行號列號的關(guān)系即可
1. 顯存地址 : B8000H - BFFFFH
2. 每一個字符占用兩個字節(jié) , 低地址為 ASCII 碼 , 高地址為屬性
可以計算出 , 假設(shè)我們要往顯存第 n 頁的第 x 行 第 y 列寫入 ascii 碼為 0x20 的字符 , 屬性為 : 11001000B (高亮閃爍黑底紅字)
3. 為了能對齊 , 我們將一頁的數(shù)據(jù)記為 80 * 25 * 2 = 4000 字節(jié) , 約為 4k
那么就應(yīng)該將 0x20 寫到 : B8000H + (n - 1) * (4 * 1024) + (x - 1) * (80) + (y - 1) 處
將屬性 11001000B 寫到 : B8000H + (n - 1) * (4 * 1024) + (x - 1) * (80) + (y - 1) + 1 處
我們這里需要將數(shù)據(jù)寫入第一頁的 dh 行 dl 列 , 假設(shè)調(diào)用的時候第一行即用 (dh) = 0 來表示
也就是說 : 
(B800H:0000H + dh * 80 + dl) = ASCII
(B800H:0000H + dh * 80 + dl + 1) = ATTR

代碼 :

assume cs:code,ds:data,ss:stack

data segment
    db "Freedom", 0
data ends

stack segment
    db 16 dup(0)
stack ends

code segment

    start:
        ; 設(shè)置數(shù)據(jù)段 
        mov ax, data
        mov ds, ax
        ; 設(shè)置棧段
        mov ax, stack
        mov ss, ax
        mov sp, 16
        ; 設(shè)置顯存段地址
        mov ax, 0B800H
        mov es, ax
        mov si, 0 ; 數(shù)據(jù)段偏移地址 , 指向第一個字符
        ; 設(shè)置顯示的位置
        mov dh, 8
        mov dl, 0
        call show_str
        jmp finish
    
    ; 功能 : 在屏幕指定位置顯示一個指定字符串
    ; 參數(shù) : dh 表示行 , dl 表示列 , ds 和 si 表示內(nèi)存中字符串的首地址
    ; 返回 : None
    show_str:
        each_chr:
            mov ch, 00H
            mov cl, ds:[si]
            jcxz over
            mov ch, 11001000B ; 設(shè)置字符屬性
            call show_chr
            inc dl ; 列數(shù)自增
            inc si ; 字符指針自增
            jmp each_chr
        over:
            ret

    ; 功能 : 在屏幕上的指定位置顯示一個指定字符
    ; 參數(shù) : dh 表示行 , dl 表示列 , cl 表示字符 , ch 表示字符的屬性
    ; 返回 : None
    show_chr:
        ; 計算相對顯存地址的偏移
        ; (行數(shù) * 80 + 列數(shù)) * 2 = 字節(jié)數(shù)
        mov al, 80
        mul dh
        push dx
        mov dh, 00H
        add ax, dx
        pop dx
        add ax, ax
        mov di, ax
        mov es:[di], cx
        ret
        
    finish:
        ; 為了能看到效果 , 這里循環(huán)執(zhí)行 nop
        jmp stop
        mov ax,4cH
        int 21H
    stop:
        nop
        jmp stop

code ends

end start

備注 :

Paste_Image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容