简体   繁体   English

如何换行并在换行中打印相同的字符

[英]How to make a new line and print the same characters in new line

I'm trying to learn assembly. 我正在尝试学习汇编。 I saw this example in printing "Hello World!(red text) with a backgound color(yellow)" 我在打印“ Hello World!(红色文本)并使用背景色(黄色)”时看到了这个示例

I managed to edit the code to just print spaces with yellow background by trial and error. 我设法通过反复试验将代码编辑为仅打印黄色背景的空格。 However I cannot print a new line. 但是,我无法打印新行。 if I add a new mov [200], ' ' for example (dont know if this is correct) it adds a character on a different line but a different color.. if I add 00010001b after the comma if prints a different color which should blue. 如果我添加一个新的mov [200], ' '例如mov [200], ' ' (不知道这是否正确),它会在不同的行上添加一个字符,但是使用不同的颜色。如果在逗号后添加00010001b ,则打印不同的颜色蓝色。

can anyone give me a head start tutorial in this code. 谁能给我这个代码的入门教程。 I just want to print another line for now.. Here is the working code so far.. it prints a whole line of yellow 我现在只想打印另一行。.这是到目前为止的工作代码..它打印一整行黄色

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

When you write directly to video memory at B800:<adr> , the address of write decides what the value will be used for (depends on selected graphics(text!) mode of course). 当您在B800:<adr>直接写入视频内存时,写入地址决定了该值将用于什么(当然取决于所选的图形(文本!)模式)。

In classic text mode 80x25 the video memory starts at B800:0000 , and has size 80*25*2 bytes. 在经典文本模式80x25中,视频内存从B800:0000开始,大小为80 * 25 * 2字节。 80*25 is probably self explanatory, 1 byte per character (in extended 8-bit ASCII encoding), so why *2? 80 * 25可能是不言自明的,每个字符1个字节(使用扩展的8位ASCII编码),那么为什么* 2? Each character has 1 more byte dedicated for colours. 每个字符还有1个专用于颜色的字节。 Actually they sit next to each other, so at B800:0000 is the ASCII value of character, and at B800:0001 is stored it's colour attribute. 实际上,它们彼此相邻,所以在B800:0000是字符的ASCII值,在B800:0001处存储了它的color属性。

Character+attribute pairs are stored from left to right row by row, so to write character '*' at position (40,12) (almost centre of screen), you have to write at address (y*160 + x*2) = (12*160 + 40*2) = 2000. The *160 is *80*2 = number of character+attribute pairs per row, ie. 字符+属性对从左到右逐行存储,因此要在位置(40,12)(屏幕的几乎中心)写入字符'*' ,必须在地址(y * 160 + x * 2)处写入=(12 * 160 + 40 * 2)=2000。* 160是* 80 * 2 =每行字符+属性对的数量,即。 size of row in bytes: 行的大小(以字节为单位):

mov   BYTE PTR [2000],'*'
mov   BYTE PTR [2001],2Eh  ; yellow ink, green paper

Or you can shorten that to single WORD write as: 或者您可以将其缩短为单个WORD,写为:

mov   WORD PTR [2000],2E00h + '*'

To print on next line you simply have to adjust the address either by +160 (to move under current character), or by adding the remaining size of row to the current address to get to the first char of next line, like +80 for the 2000 from example to move at the beginning of line 13 (14th line on screen). 要在下一行上打印,您只需将地址调整+160(以在当前字符下移动),或通过将行的剩余大小添加到当前地址以获取下一行的第一个字符,例如+80示例中的2000 ,移至第13行的开头(屏幕上的第14行)。

See this page for further details about video memory layout: 有关视频内存布局的更多详细信息,请参见此页面:
http://www.shikadi.net/moddingwiki/B800_Text http://www.shikadi.net/moddingwiki/B800_Text


BTW the more bytes you write at one time, the faster the code runs on real (original) HW, so in your case I would strongly prefer either the WORD write storing the ASCII+attribute pair together, or even DWORD writes (in 32b mode) storing two letters+two attributes with single instruction. 顺便说一句,您一次写入的字节越多,代码在实际(原始)硬件上运行的速度就越快,因此在您的情况下,我强烈希望将ASCII +属性对存储在一起的WORD写入,甚至是DWORD写入(在32b模式下) )用一条指令存储两个字母+两个属性。

Your code does first write every second byte on even addresses setting the ASCII letters, then it does write every odd byte with colour value. 您的代码会先在设置ASCII字母的偶数地址上每隔第二个字节写入一次,然后便将每个带有颜色值的奇数字节写入一次。 I would do it in this way personally: 我将以这种方式亲自进行操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM