实验九
1. 概念
-
B8000H~BFFFFH 共 32KB 的空间, 为 80x25 彩色字符模式的显示缓冲区。向这个地址空间写入数据, 写入的内容将立即出现在显示器上。
-
在 80x25 彩色字符模式下, 显示器可以显示 25 行, 每行 80 个字符, 每个字符可以有 256 种属性(背景色、前景色、闪烁、高亮等组合信息)
-
这样, 一个字符在显示缓冲区中就要占两个字节, 分别存放字符的 ASCII 码和属性。80x25 模式下, 一屏的内容在显示缓冲区中共占 4000 个字节。
-
显示缓冲区分为 8 页, 每页 4KB(≈4000B = 80x2x25,80 个字符, 偶数列, 80 个颜色控制, 奇数列), 显示器可以显示任意一页的内容。一般清空下, 显示第 0 页的内容。也就是通常情况下, B8000H~B8F9FH 中的 4000 个字节的内容将出现在显示器上。
2. 题目
题目:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串‘welcome to masm!’。
第1页第1行:80x2, B800: 范围0 - 159, 最后一个字符位置: 158=9E, 最后一个颜色位:159=9F
第1页第2行:80x2, B800: 范围160 - 319, 最后一个字符位置:318=13E,最后一个颜色位:319=13F
颜色属性:7 6 5 4 3 2 1 0
颜色属性:BL R G B I R G B
颜色属性:闪烁 背景 高亮 前景色
绿色字符:0 0 0 0 0 0 1 0 = 2H
绿底红色:0 0 1 0 0 1 0 0 = 24H
白底蓝色:0 1 1 1 0 0 0 1 = 71H
黑底白色:0 0 0 0 0 1 1 1 = 7H
比如:单一绿色加字符 高位:颜色 低位:字符
-e b800:0
B800:0000 C9.77 1F.02 CD.65 1F.02 CD.6C 1F.02
-d b800:0
B800:0000 77 02 65 02 6C 02 CD 1F-CD 1F CD 1F CD 1F CD 1F w.e.l...........
assume cs:code,ds:data
data segment
; 0123456789ABCDEF
; welcome to masm!
; dh 颜色, dl 字符
db 'welcome to masm!'
db 00000010B ; 绿色
db 00100100B ; 绿底红色
db 01110001B ; 白底蓝色
data ends
code segment
start:
jmp show_masm
next:
mov ax,4c00h
int 21h
show_masm:
mov bx, data
mov ds,bx
; -d ds:0 1F
; 0E24:0000 77 65 6C 63 6F 6D 65 20-74 6F 20 6D 61 73 6D 21 welcome to masm!
; 0E24:0010 02 24 71 00 00 00 00 00-00 00 00 00 00 00 00 00 .$q.............
; 因为dosbox显示会往上推, 先用2000H方便查看
; mov bx,0B800H ; 数据放到哪里去
mov bx,2000H ; 数据放到哪里去
mov es,bx
mov di, 160*12 + 30*2 ; 中间位置, 伪指令 es:[di],07BCH
; -d es:0 2F
; B800:0000 C8 1F CD 1F CD 1F CD 1F-CD 1F CD 1F CD 1F CD 1F
; B800:0010 CA 02 B9 02 D3 02 C3 02-20 02 44 02 4F 02 53 02
; B800:0020 36 07 20 07 20 07 20 07-20 07 20 07 20 07 20 07
; -r
; AX=0000 BX=B800 CX=005A DX=0000 SP=0000 BP=0000 SI=0000 DI=07BC
; DS=0E24 ES=B800 SS=0E23 CS=0E26 IP=0014 NV UP EI PL NZ NA PO NC
; 0E26:0014 B90300 MOV CX,0003
mov cx,3 ; 三个颜色
mov bx,16 ; 颜色位置 ds:[bx]
show_masm1:
push cx
push di
; -d ss:FFF0
; 0E23:FFF0 00 00 00 00 00 00 1C 00-26 0E 21 08 BC 07 03 00
mov cx,16
mov si,0 ; 起始位置 ds:[si]
mov dh,ds:[bx] ; 设置颜色为绿色
show_str:
mov dl, ds:[si]
mov es:[di],dx
add di,2
inc si
loop show_str
; 复制第一行加颜色 02 绿色
; 0E26:002D E2F5 LOOP 0024
; -p
; AX=0000 BX=0010 CX=0000 DX=0221 SP=FFFC BP=0000 SI=0010 DI=07DC
; DS=0E24 ES=2000 SS=0E23 CS=0E26 IP=002F NV UP EI PL NZ AC PO NC
; 0E26:002F 5F POP DI
; -d es:07b0
; 2000:07B0 00 00 00 00 00 00 00 00-00 00 00 00 77 02 65 02 ............w.e.
; 2000:07C0 6C 02 63 02 6F 02 6D 02-65 02 20 02 74 02 6F 02 l.c.o.m.e. .t.o.
; 2000:07D0 20 02 6D 02 61 02 73 02-6D 02 21 02 00 00 00 00 .m.a.s.m.!.....
; 第二行
; -d es:0850
; 2000:0850 00 00 00 00 00 00 00 00-00 00 00 00 77 24 65 24 ............w$e$
; 2000:0860 6C 24 63 24 6F 24 6D 24-65 24 20 24 74 24 6F 24 l$c$o$m$e$ $t$o$
; 2000:0870 20 24 6D 24 61 24 73 24-6D 24 21 24 00 00 00 00 $m$a$s$m$!$....
; 第三行
; -d es:08F0
; 2000:08F0 00 00 00 00 00 00 00 00-00 00 00 00 77 71 65 71 ............wqeq
; 2000:0900 6C 71 63 71 6F 71 6D 71-65 71 20 71 74 71 6F 71 lqcqoqmqeq qtqoq
; 2000:0910 20 71 6D 71 61 71 73 71-6D 71 21 71 00 00 00 00 qmqaqsqmq!q....
pop di
pop cx
add di,160 ; 下一行 085CH、08FCH
inc bx ; 下个颜色, 24H、71H
loop show_masm1
jmp next
code ends
end start