我设法编辑代码,只是通过反复试验打印黄色背景的空格。但是我无法打印新行。如果我添加一个新的mov [200], ' '
例如(不知道这是否正确)它会在不同的行上添加一个字符但颜色不同..如果我在逗号后添加00010001b
如果打印不同的颜色应该是蓝色的。
任何人都可以在这段代码中给我一个启动教程。我现在只想打印另一行。这是到目前为止的工作代码..它打印整行黄色
name "hi-world"
; hex bin color ; ; 0 0000 black ; 1 0001 blue ; 2 0010 green ; 3 0011 cyan ; 4 0100 red ; 5 0101 magenta ; 6 0110 brown ; 7 0111 light gray ; 8 1000 dark gray ; 9 1001 light blue ; a 1010 light green ; b 1011 light cyan ; c 1100 light red ; d 1101 light magenta ; e 1110 yellow ; f 1111 white
org 100h
; set video mode mov ax, 3 ; text mode 80x25, 16 colors, 8 pages (ah=0, al=3) int 10h ; do it!
; cancel blinking and enable all 16 colors: mov ax, 1003h mov bx, 0 int 10h
; set segment register: mov ax, 0b800h mov ds, ax
; print "hello world" ; first byte is ascii code, second byte is color code.
mov [02h], ' '
mov [04h], ' '
mov [06h], ' '
mov [08h], ' '
mov [0ah], ' '
mov [0ch], ' '
mov [0eh], ' '
mov [10h], ' '
mov [12h], ' '
mov [14h], ' '
mov [16h], ' '
mov [18h], ' '
mov [1ah], ' '
mov [1ch], ' '
mov [1eh], ' '
mov [20h], ' '
; color all characters: mov cx, 34 ; number of characters. mov di, 03h ; start from byte after 'h'
c: mov [di], 11101100b ; light red(1100) on yellow(1110)
add di, 2 ; skip over next ascii code in vga memory.
loop c
; wait for any key press: mov ah, 0 int 16h
ret
答案 0 :(得分:2)
当您在B800:<adr>
处直接写入视频内存时,写入地址决定了该值的用途(当然取决于所选图形(文本!)模式)。
在经典文本模式80x25中,视频内存从B800:0000
开始,大小为80 * 25 * 2字节。 80 * 25可能是自解释的,每个字符1个字节(扩展的8位ASCII编码),为什么* 2?每个字符还有1个专用于颜色的字节。实际上它们彼此相邻,所以在B800:0000
是字符的ASCII值,在B800:0001
存储它的颜色属性。
字符+属性对从左到右逐行存储,因此要在位置(40,12)(几乎是屏幕中心)写字符'*'
,你必须在地址处写入(y * 160) + x * 2)=(12 * 160 + 40 * 2)= 2000. * 160是* 80 * 2 =每行的字符+属性对的数量,即。行的大小(以字节为单位):
mov BYTE PTR [2000],'*'
mov BYTE PTR [2001],2Eh ; yellow ink, green paper
或者您可以将其缩短为单个WORD写为:
mov WORD PTR [2000],2E00h + '*'
要在下一行打印,您只需要调整地址+160(在当前字符下移动),或者将剩余的行大小添加到当前地址以获取下一行的第一个字符,例如+ 2000
示例中的mov ax,0B800h
mov es,ax
mov di,<target_address = y*160 + x*2> ; es:di set up
mov ah,<color_attribute_for_whole_string>
; now the print by letter gets here
mov al,'H' ; al = letter, ah = attribute (ax set up)
stosw ; [es:di] = ax, di += 2
mov al,'e' ; change only letter in ax
stosw
mov al,'l'
stosw
mov al,'l'
stosw
...
; the mov al,<char> can be replaced by LODSB
; reading ascii string from ds:si.
; then it would look like:
mov si,<address_of_ascii_string>
lodsb
stosw
lodsb
stosw
... so many times as the string length
移动到第13行的开头(屏幕上的第14行)。
有关视频内存布局的更多详细信息,请参阅此页面:
http://www.shikadi.net/moddingwiki/B800_Text
BTW你一次写的字节越多,代码在真实(原始)硬件上运行的速度就越快,所以在你的情况下,我强烈要求WORD写入存储ASCII +属性对,甚至DWORD写入(在32b模式下)用单指令存储两个字母+两个属性。
您的代码首先在设置ASCII字母的偶数地址上写入每隔一个字节,然后它会用颜色值写入每个奇数字节。我会亲自这样做:
use FacadeAlias