x86汇编学习 ----- 九
在屏幕中显示字符串
在学习汇编语言的这段日子中,每次都在想如何显示字符串于屏幕之上,就像printf函数那样,因为每次调试汇编时都在debug窗口中利用d指令来查看内存中得信息,很是不直观呀。今天研究王爽的《汇编语言(第2版)》实验9一个下午了,终于是有了成就。
该实验目的:在屏幕中间分别显示绿色(默认黑底),绿底红色,白底蓝色的字符串“Welcome to masm!”。
看到这个实验室,我是激动万分呀,因为可以小小满足一下自己对显示字符的渴望呀。好吧,废话不多说,应该进入正题了。
==================================正===================================================
------------------------------------------------------“划时代”的日子--------------------------------------------------------------------------------
这是一个根据材料的编程题。
我们用得时80x25彩色字符模式缓冲区的结构,当然也有单色模式了(其内存地址空间要靠自己去探索咯哟)。
80x25彩色字符模式显示缓冲区的内存地址是0xB8000~0xBFFFF共32K。向这个地址空间写入数据就会显示在屏幕上了,呵呵,这就是核心原理咯,至于是怎么显示,为什么显示那些颜色只有稍等咯
80x25彩色字符模式下,显示器可以显示25行,每行80个字符,而每个字符2个字节,第一个字节是该字符的ASCII码值,第二个字节是该字符的属性(闪烁,背景颜色,高亮以及前景颜色的组合信息)
显示缓冲区分为8页,每一页32K/8=4K字节。显示器可以显示每一页的内容,一般显示在第0页,也就是当前页。也就是B8000~B8F9F地址空间中。
下面说一下属性值吧。
位 7 6 5 4 3 2 1 0
BL R G B I R G B
含义 闪烁 背 景 高亮 前 景
R-----红色 G-------绿色 B-----------蓝色
当上面的某个位值为1则有效。比如
红底绿字属性值:01000010B 42h
红底高亮绿字属性值01001010B 4Ah
红底闪烁字属性值11000010B C2h
当然RGB一共能组合出8种颜色,所以这些位就赋予一个字符2^8=256种属性。
注意:闪烁效果应在纯DOS下才能看到
现在回到编程题吧,你也一定知道如何做了吧!
绿字 :00000010B 02h
绿底红字 :00100100B 24h
白底蓝字 :01110001B 71h
好吧,下面附上源代码,源码有一定的解释
assume cs:code,ds:data,ss:stack
data segment
db 'Welcome to masm!' ;要显示的字符串
db 02h,24h,71h ;三个颜色值分别是 绿色,绿底红色,白底蓝色
data ends
stack segment
dw 8 dup(0) ;堆栈保存每层循环的变量
stack ends
code segment
start: mov ax,data
mov ds,ax ;将data段与ds关联
mov ax,stack
mov ss,ax ;将stack段与ss关联
mov sp,10h ;设置栈顶
xor bx,bx ;mov bx,0一个效果
mov ax,0b872h ;放置第一个字符串的首地址
mov cx,3 ;外循环,显示字符串Welcome to masm!三次
S3: push cx ;由于有多重循环,所以用堆栈保存外循环次数
push ax ;用于保存显示三次字符串的显存首地址
push bx ;用来索引颜色值
mov es,ax ;将显示字符串的显存地址用一个段表示
mov si,0 ;索引字符串的字符
mov di,0 ;指示字符和颜色属性放置的位置
mov cx,10h ;内层循环次数,也就是放置16个字符次数
;一下循环S1将字符放置到其位置
S1: mov al,ds:[si]
mov es:[di],al
inc si
add di,2 ;每个字符占有两个字节(字符ASCII以及属性)
loop S1
mov di,1
pop bx
mov al,ds:10h[bx] ;拿到颜色属性
inc bx
;S2放置颜色属性
mov cx,10h
S2: mov es:[di],al
add di,2
loop S2
pop ax
add ax,0ah
pop cx
loop S3
mov ax,4c00h
int 21h
code ends
end start
带一张运行效果图(XP下的,WIN7运行不出来,因为其不支持全屏模式)