而且要明白这段地址不是主板上内存条上的内存地址,内存条只是地址总线可以达到的范围中的一小部分,指令需要什么数据,地址总线会帮我们去找。地址只是数字,地址总线把地址拿到后,用此数字指向哪个存储介质,此地址就指向了那个介质上的存储单元中,所以一个地址的数字到底是指向哪里,是由地址总线说了算的。
从B8000到BFFFF这32KB大小的内存中输出的字符会直接落到显存中,显存有了数据,显卡自然就会把它搬到显示器上。
显卡的文本模式也分很多种模式的,用行列来表示,也就是80*25,40*25,80*43这些,他们的乘积表示屏幕上可以容纳的字符数,在显卡开始工作时,默认就是80*25,也就是一个屏幕可以打印2000个字符。虽说是文本模式,但不代表不可以打印彩色字符,当然,如果要打印彩色字符,一个字符一个字节就没办法了,ASCII码都是一个字节大小,即使标准的ASCII也是用7位编码,剩下的一位只能表示黑白了,所以我们需要两个字节来表示一个字符。一个屏幕2000个字符,一个字符2个字节,也就是一个屏幕需要4000字节,文本模式拥有32KB显存,所以32KB/4000B大约是八个屏幕大小(你应该想到Linux的tty切换了吧)。
既然确定了每个字符所用的字节大小,那么这两个字节如何分配呢?
屏幕上每个字符的低字节是字符的ASCII码,高字节是字符的属性信息。高字节中低四位是字符的前景色,高四位是背景色,都是RGB三色调和,对于每四位来说,RGB占据了三位,那么还有一位呢? 每四位的最高一位是用来表示亮色或者暗色。具体分配如下:
bit
K(控制是否闪烁) 15
R 14
G 13
B 12
I(亮度位) 11
R 10
G 9
B 8
字符ASCII码 0 ~ 7
新的代码只要把之前的BIOS中断部分换掉就可以了,在0xB800H处写入数据即可
1 SECTION MBR vstart=0x7c00 2 mov ax,cs 3 mov ds,ax 4 mov es,ax 5 mov ss,ax 6 mov fs,ax 7 mov sp,0x7c00 8 mov ax,0xb800 9 mov gs,ax 10 11 mov ax,0x600 12 mov bx,0x700 13 mov cx,0 14 mov dx,0x1010 15 int 0x10 16 17 mov byte [gs:0x00],'A' 18 mov byte [gs:0x01],0xA4 19 20 mov byte [gs:0x02],'n' 21 mov byte [gs:0x03],0x13 22 23 mov byte [gs:0x04],'t' 24 mov byte [gs:0x05],0x52 25 26 mov byte [gs:0x06],'z' 27 mov byte [gs:0x07],0xB1 28 29 mov byte [gs:0x08],' ' 30 mov byte [gs:0x09],0xCC 31 32 mov byte [gs:0x0A],'U' 33 mov byte [gs:0x0B],0x2B 34 35 mov byte [gs:0x0C],'h' 36 mov byte [gs:0x0D],0x6D 37 38 mov byte [gs:0x0E],'l' 39 mov byte [gs:0x0F],0x7E 40 41 mov byte [gs:0x10],' ' 42 mov byte [gs:0x11],0x49 43 44 mov byte [gs:0x12],'K' 45 mov byte [gs:0x13],0xE5 46 47 mov byte [gs:0x14],'o' 48 mov byte [gs:0x15],0x8A 49 50 mov byte [gs:0x16],'n' 51 mov byte [gs:0x17],0x96 52 53 mov byte [gs:0x18],'e' 54 mov byte [gs:0x19],0x68 55 jmp $ 56 57 times 510-($-$$) db 0 58 db 0x55,0xaa