【发布时间】:2019-04-20 22:23:34
【问题描述】:
如何在程序集 8086 中使字符串着色?
【问题讨论】:
-
Int 10h/ah=9 不设置光标。它以指定的颜色打印字符。即使你已经设置了光标 - 0,0 是左上角(不是右)
-
那我应该先做ah=9和int 10h再设置光标?
如何在程序集 8086 中使字符串着色?
【问题讨论】:
你使用了错误的中断函数:
INT 10h, AH=09h 一次打印多个相同的字符。计数在CX 寄存器中传递。要打印字符串,您必须像字符串中的字符一样频繁地调用它,并设置其他参数。字符必须在AL 寄存器中传递,属性/颜色必须在BL 寄存器中传递。 BH 应该(可能)保持0 和CX 应该保持1。此函数不使用DL 和DH,因此您可以删除相应的命令。
初始光标位置可以通过INT 10h, AH=02h函数来设置。确保BH 值与上述代码中的值匹配(0)。
所以您的代码可能如下所示:
; ...
; Print character of message
; Make sure that your data segment DS is properly set
MOV SI, offset Msg
mov DI, 0 ; Initial column position
lop:
; Set cursor position
MOV AH, 02h
MOV BH, 00h ; Set page number
MOV DX, DI ; COLUMN number in low BYTE
MOV DH, 0 ; ROW number in high BYTE
INT 10h
LODSB ; load current character from DS:SI to AL and increment SI
CMP AL, '$' ; Is string-end reached?
JE fin ; If yes, continue
; Print current char
MOV AH,09H
MOV BH, 0 ; Set page number
MOV BL, 4 ; Color (RED)
MOV CX, 1 ; Character count
INT 10h
INC DI ; Increase column position
jmp lop
fin:
; ...
DOS函数INT 21h打印一个字符串直到结束字符$不关心传递给BIOS函数INT 10h的属性,所以颜色被它忽略了,你可以删除相应的代码从;print the string 到INT 21h。
【讨论】:
DS:SI 作为源字符串,ES:DI 作为屏幕缓冲区。然后您可以利用字符串指令LODSB 和STOSW。
zx485 的答案中已经解释了为什么您当前的程序不起作用。根据your comment,您确实可以一次性打印整个彩色字符串。 BIOS 为我们提供video function 13h。 ES:BP 中应包含指向文本的完整指针,因此请确保正确设置了 ES 段寄存器。
score db '12345'
...
PROC PrintScore
pusha
mov bp, offset score ; ES:BP points at text
mov dx, 0000h ; DH=Row 0, DL=Column 0
mov cx, 5 ; Length of the text
mov bx, 0004h ; BH=Display page 0, BL=Attribute RedOnBlack
mov ax, 1300h ; AH=Function number 13h, AL=WriteMode 0
int 10h
popa
ret
ENDP PrintScore
【讨论】: