[英]How to change the foreground color of a string (32 Bit Assembly kernel)?
我目前正在编写自己的操作系统(只是为了好玩,我16岁)并且我已经创建了outprint功能的问题。 我想更改文本颜色(不是背景颜色),但它不起作用。
我创建了自己的printf
函数SystemOutPrint/ln
(以Java命名,因为我的“主要”语言,对于那些有意思的人),并且发现我可以通过写入AH寄存器来改变背景颜色。 在此函数之前,我根本没有在内核中执行任何操作,并且引导加载程序仅将GDT,LDT和模式设置为16到32位。 所以视频内存不受影响,直到mov ebx,0xb8000。
相关代码 :
kmain:
mov ebx, 0xb8000 ;Video Memory
mov esi, kernelVersion
mov ah, 0x0
;setting ah to 0x0 is not neccessary, because its the default but if you
;would put in A for example it would be light green, etc.
call SystemOutPrintln
SystemOutPrintln:
mov ecx, ebx
.printChar:
lodsb
test al,al
jz .newLine
or eax,0x0F00
mov word [ebx], ax
add ebx, 2
jmp .printChar
.newLine:
mov edx, ebx
sub edx, ecx
mov ecx, 0x000A0
sub ecx, edx
add ebx, ecx
ret
kernelVersion: db "Kernel Version: 0.0.1", 0
我尝试了什么:更改eax中的每个字节以查找foregound颜色的属性字节。 通过这样尝试和错误,我发现,改变啊适用于背景颜色,但al用于测试al,al来找到字符串的结尾,而不是ax的eax部分被简单地解除了功能。 我没有尝试改变其他寄存器中的某些东西,因为它们用于其他东西或者根本没有用,所以它并没有给我看。 一个网站(我没有找到链接它)说,属性字节的定义如下:BG颜色的十六进制值(比如白色的F)* 16 = F0 + FG颜色的十六进制值(让A取浅绿色)什么应该是FA。 如果我做“mov ah,0xFA”我将背景更改为白色,但前景仍为白色(默认)。
为此提供一个最小的可重复示例将不再是最小的,因为我将不得不给你bootloader和GDT。 但是,如果有人能告诉我哪个字节是前景色属性字节,那就足够了答案,所以我可以专注于尝试让该字节工作而不必在尝试和错误中重写整个视频记录。
第一; 让我们稍微优化你的代码。 具体来说,对于这个循环:
.printChar:
lodsb
or al,al
jz .newLine
or eax,0x0F00
mov word [ebx], ax
add ebx, 2
jmp .printChar
..在第一次迭代之后, ah
的值不会改变; 这样可以将指令从循环中取出以提高性能。 or eax,0x0F000
也or eax,0x0F000
与or eax,0x0F000
or ah,0x0F
具有相同的效果。 这两个变化最终都是这样的:
or ah,0x0F
.printChar:
lodsb
or al,al
jz .newLine
mov word [ebx], ax
add ebx, 2
jmp .printChar
现在添加一些评论,如下所示:
or ah,0x0F ;Force the foreground colour for all characters to be white
.printChar:
lodsb ;al = next character
or al,al ;Is the next character zero?
jz .newLine ; yes, don't print it and move to the next line instead
mov word [ebx], ax ;Store next character (from string) and attribute (from outside the loop)
add ebx, 2 ;bx = address to store next character and attribute
jmp .printChar
请注意,注释(例如“强制所有字符的前景色为白色”)非常有用,因为:
它们减少了理解代码应该做什么所花费的时间
他们可以很容易地看到错误,其中指令没有按照评论所说的那样做
我无法更改FG颜色的原因是或者是eax, 0x0f00
。
f
是应该定义前景色的半字节,但由于or
,我之前放入的所有内容都被覆盖了。 感谢Peter Cordes问我为什么“在循环中使用或eax, 0x0f00
而不是仅在循环外设置AH”。 由于这个原因我试图离开or
离开它并且它的工作原理应该如何,只是不要忽略我之前设置的FG。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.