延伸探讨...
其实显示颜色字串不一定需要直接写显存,bios提供的int10h,函数13h就可以做到,参数分别是
es:bp=字串起点,cx=字串长度,bl=颜色,dl=列,dh=行,al=模式,通常=0,然后ah=13h,调用int10h就是.
另外,若配合masm提供的宏,写颜色字串会是十分简单的操作.
masm, m + asm, macro assembler, 就是宏汇编器的意思,宏写法是
@宏名称 MACRO 参数1,参数2....参数n
宏本身
ENDM
把显示字串写成一个宏,放在文件最前
@DispStr MACRO DStr,Column,Row,Color
..
..
ENDM
比如要在座标(10,3)输出Strbuf字串,颜色=绿,一句指令就可以
@DispStr StrBuf,10,3,2
下面是将show_str子程序改为宏,为了检证这个宏能处理不同长度的字串,分别用了三个大小不一的数字.
程序代码:
.286
;--------------------------------------------------------------------------------------------------
;显示颜色字串的宏
@DispStr MACRO DStr,Column,Row,Color ;调用int10h,ah=13h输出颜色字串,4参数分别是字串,列,行,颜色
pusha ;保存所有寄存器
push es ;保存ES
push ds ;
pop es ;ES=DS ------------------------------------------|
lea di,DStr ;取得字串地址 |
mov al,0 ;AL=0 |
mov cx,0ffffh ;最大初始化值 |
cld ;清除方向 |--找字串长度
repnz scasb ;重覆找es:di中(cx=长度)有没有al,找到则零标志=0 |
jnz @f ;找不到,离开 |
sub cx,0ffffh ;减去初始值 |
not cx ;反,得cx=字串长度-----------------------------------|
lea bp,DStr ;取得字串地址 -------------------------------------------------|
mov bl,Color ;颜色 |
mov bh,0 ;显示页=0 | int10h
mov dh,Row ;行(x) |--ah=13h
mov dl,Column ;列(y) | 输出函数
mov ax,1300h ;输出字串函数,dl=列,dh=行,bl=色,cx=长度,es:bp=字串地址,al=模式0 |
int 10h ;调用int10h -----------------------------------------------|
@@:
pop es ;取回es
popa ;取回所有寄存器
ENDM ;宏结束
;--------------------------------------------------------------------------------------------------
DATA SEGMENT
StrBuf db 10 dup(0)
DATA ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATA
START:
mov ax,data
mov ds,ax
mov es,ax
cld ;清除方向标志
mov ax,12666 ;任意值
lea di,StrBuf ;数字字串地址
call htod ;转换ax值为数字字串
@DispStr StrBuf,3,8,2 ;绿色=2
mov ax,54 ;任意值
lea di,StrBuf ;数字字串地址
call htod ;转换ax值为数字字串
@DispStr StrBuf,20,11,6 ;黄色=6
mov ax,1234 ;任意值
lea di,StrBuf ;数字字串地址
call htod ;转换ax值为数字字串
@DispStr StrBuf,50,20,0Bh ;亮蓝色=0bh
mov ax,4c00h
int 21h
htod: ;输出数值转字符串并存入es:di的子程序
mov cx,0 ;清0,初如化
mov bx,10 ;除法准备
@@:
mov dx,0 ;清0
div bx ;ax /10,若1234,除10后,dl得余数4
push dx ;保存, ax=1234,依次保存4,3,2,1
inc cx ;累加个数
or ax,ax ;是否已除尽
jnz @b ;不是,再除
@@:
pop ax ;后入先出,先印出第一数,然后第二....
or al,'0' ;转ascii
stosb ;存入es:[di],di+1
loop @b ;下一个
mov al,0 ;0结束符
stosb ;存入es:[di],作为结束符
ret
CODES ENDS
END START
图片附件: 游客没有浏览图片的权限,请
登录 或
注册
[此贴子已经被作者于2020-7-31 20:37编辑过]