簡介 :
子程序描述 :
名稱 : show_str
功能 : 在指定的位置顯示一個用 0 結束的字符串
參數 : (dh) = 行號 (0-24) , (dl) = 列號 (0-79)
返回 : None
分析 :
根據之前的分析 , 我們已經了解了顯存的范圍等等信息
也知道了只要往顯存中寫入數據 , 就可以顯示到對應的位置
我們這里需要做的一件事就是搞清楚顯存地址和行號列號的關系即可
1. 顯存地址 : B8000H - BFFFFH
2. 每一個字符占用兩個字節 , 低地址為 ASCII 碼 , 高地址為屬性
可以計算出 , 假設我們要往顯存第 n 頁的第 x 行 第 y 列寫入 ascii 碼為 0x20 的字符 , 屬性為 : 11001000B (高亮閃爍黑底紅字)
3. 為了能對齊 , 我們將一頁的數據記為 80 * 25 * 2 = 4000 字節 , 約為 4k
那么就應該將 0x20 寫到 : B8000H + (n - 1) * (4 * 1024) + (x - 1) * (80) + (y - 1) 處
將屬性 11001000B 寫到 : B8000H + (n - 1) * (4 * 1024) + (x - 1) * (80) + (y - 1) + 1 處
我們這里需要將數據寫入第一頁的 dh 行 dl 列 , 假設調用的時候第一行即用 (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:
; 設置數據段
mov ax, data
mov ds, ax
; 設置棧段
mov ax, stack
mov ss, ax
mov sp, 16
; 設置顯存段地址
mov ax, 0B800H
mov es, ax
mov si, 0 ; 數據段偏移地址 , 指向第一個字符
; 設置顯示的位置
mov dh, 8
mov dl, 0
call show_str
jmp finish
; 功能 : 在屏幕指定位置顯示一個指定字符串
; 參數 : dh 表示行 , dl 表示列 , ds 和 si 表示內存中字符串的首地址
; 返回 : None
show_str:
each_chr:
mov ch, 00H
mov cl, ds:[si]
jcxz over
mov ch, 11001000B ; 設置字符屬性
call show_chr
inc dl ; 列數自增
inc si ; 字符指針自增
jmp each_chr
over:
ret
; 功能 : 在屏幕上的指定位置顯示一個指定字符
; 參數 : dh 表示行 , dl 表示列 , cl 表示字符 , ch 表示字符的屬性
; 返回 : None
show_chr:
; 計算相對顯存地址的偏移
; (行數 * 80 + 列數) * 2 = 字節數
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:
; 為了能看到效果 , 這里循環執行 nop
jmp stop
mov ax,4cH
int 21H
stop:
nop
jmp stop
code ends
end start
備注 :
Paste_Image.png