In the sections of Chapter 5 to Chapter 7 of "x86 Assembly Language: From Real Mode to Protected Mode" by Teacher Li Zhong, each chapter uses three different methods of displaying characters while telling the knowledge points, plus the method of calling the BIOS's 10h interrupt. Here is a simple review:
1: Chapter 5, the most basic method of using mov directly
The code is as follows:
;Code list5-1 ;file name:c05_mbr.asm ;Document description:Hard disk main boot sector code ;Creation date:2011-3-31 21:15 mov ax,0xb800 ;Display buffer pointing to text mode mov es,ax ;The following displays the string"Label offset:" mov byte [es:0x00],'L' mov byte [es:0x01],0x07 mov byte [es:0x02],'a' mov byte [es:0x03],0x07 mov byte [es:0x04],'b' mov byte [es:0x05],0x07 mov byte [es:0x06],'e' mov byte [es:0x07],0x07 mov byte [es:0x08],'l' mov byte [es:0x09],0x07 mov byte [es:0x0a],' ' mov byte [es:0x0b],0x07 mov byte [es:0x0c],"o" mov byte [es:0x0d],0x07 mov byte [es:0x0e],'f' mov byte [es:0x0f],0x07 mov byte [es:0x10],'f' mov byte [es:0x11],0x07 mov byte [es:0x12],'s' mov byte [es:0x13],0x07 mov byte [es:0x14],'e' mov byte [es:0x15],0x07 mov byte [es:0x16],'t' mov byte [es:0x17],0x07 mov byte [es:0x18],':' mov byte [es:0x19],0x07 mov ax,number ;Obtain the labelnumberOffset address mov bx,10 ;Set the base address of the data segment mov cx,cs mov ds,cx ;Find the number in the single digit mov dx,0 div bx mov [0x7c00+number+0x00],dl ;Save numbers on individual digits ;Find the number in ten digits xor dx,dx div bx mov [0x7c00+number+0x01],dl ;Save the number on ten digits ;Find the number in the hundred digits xor dx,dx div bx mov [0x7c00+number+0x02],dl ;Save the number on a hundred digits ;Find the number in a thousand digits xor dx,dx div bx mov [0x7c00+number+0x03],dl ;Save the numbers on thousands ;Find the number in ten thousand digits xor dx,dx div bx mov [0x7c00+number+0x04],dl ;Save the numbers in ten thousand digits ;以下用十进制显示标号Offset address mov al,[0x7c00+number+0x04] add al,0x30 mov [es:0x1a],al mov byte [es:0x1b],0x04 mov al,[0x7c00+number+0x03] add al,0x30 mov [es:0x1c],al mov byte [es:0x1d],0x04 mov al,[0x7c00+number+0x02] add al,0x30 mov [es:0x1e],al mov byte [es:0x1f],0x04 mov al,[0x7c00+number+0x01] add al,0x30 mov [es:0x20],al mov byte [es:0x21],0x04 mov al,[0x7c00+number+0x00] add al,0x30 mov [es:0x22],al mov byte [es:0x23],0x04 mov byte [es:0x24],'D' mov byte [es:0x25],0x07 infi: jmp near infi ;Infinite loop number db 0,0,0,0,0 times 203 db 0 db 0x55,0xaa
The most basic approach adopted here is to process characters one by one. First assign the address 0xb800 of the display buffer to the es register, and then process subsequent characters through the form of mov byte[es:0x00],'L'. This method is relatively simple, so I won't go into details here.
2: Chapter 6, batch processing method is adopted
The code is as follows:
;Code list6-1 ;file name:c06_mbr.asm ;Document description:Hard disk main boot sector code ;Creation date:2011-4-12 22:12 jmp near start mytext db 'L',0x07,'a',0x07,'b',0x07,'e',0x07,'l',0x07,' ',0x07,'o',0x07,\ 'f',0x07,'f',0x07,'s',0x07,'e',0x07,'t',0x07,':',0x07 number db 0,0,0,0,0 start: mov ax,0x7c0 ;Set the base address of the data segment mov ds,ax mov ax,0xb800 ;Set additional segment base address mov es,ax cld mov si,mytext mov di,0 mov cx,(number-mytext)/2 ;Actually equals 13 rep movsw ;Get the offset address represented by the label mov ax,number ;Calculate individual digits mov bx,ax mov cx,5 ;Number of cycles mov si,10 ;divisor digit: xor dx,dx div si mov [bx],dl ;Save digital inc bx loop digit ;Display each digit mov bx,number mov si,4 show: mov al,[bx+si] add al,0x30 mov ah,0x04 mov [es:di],ax add di,2 dec si jns show mov word [es:di],0x0744 jmp near $ times 510-($-$$) db 0 db 0x55,0xaa
The method used here is batch transmission and subsequently use loop loops to process one by one. This writing method is obviously more clever than the previous one, reducing the workload. What is worth noting in this code is mov si,mytext (where mytext is the address of the declared character). One of the reasons why it is worth noting here is that when encoding the display time, there is the following writing method, so I will pay special attention.
org 7c00h start1: mov ax, cs ; Set other segment register values andCSsame mov ds, ax ; Data segment mov es, ax mov bl, 10h mov bp, Message1 mov ah, 02h int 1ah xor ax, ax mov al, ch div bl add al, 0x30 mov [es:bp+2], al add ah, 0x30 mov [es:bp+3], ah xor ax, ax mov al, cl div bl add al, 0x30 mov [es:bp+5], al add ah, 0x30 mov [es:bp+6], ah xor ax, ax mov al, dh div bl add al, 0x30 mov [es:bp+8], al add ah, 0x30 mov [es:bp+9], ah mov dh, 3 mov dl, 0 mov ax, 1301h ; Function number mov bp, Message1 mov cx, MessageLength1 mov bx, 0007h int 10h ; ret Message1: db ' 00:00:00' MessageLength1 equ ($-Message1) times 510-($-$$) db 0 ; use0Fill in the remaining space in the boot sector db 55h, 0aah ; Boot sector end flag
(The function of the above code is to call the BIOS to interrupt the system time) In this code, for the processing method of "00:00:00", the mytext field at batch processing si in code 2 is similar. Here is a mark.
Regarding the method of displaying numbers in code 2, the loop loop is used. First, use the "divided by 10" to get the value of each digit, then add it to 0x30 (the knowledge about ASCII can explain why this is why), and then assign the final value to the incremented video memory address corresponding to the incremented video memory address until each digit of the previous process is displayed, over.
Three: Chapter 7, Use the stack to operate
The special thing about the code in this chapter is that after taking the strings one by one, pressing them in order, and then rolling them out in order and processing them.
;Code list7-1 jmp near start message db '1+2+3+...+100=' start: mov ax,0x7c0 ;Set the segment base address of the data segment mov ds,ax mov ax,0xb800 ;Set the additional segment base address to the display buffer mov es,ax ;The following displays the string mov si,message mov di,0 mov cx,start-message @g: mov al,[si] mov [es:di],al inc di mov byte [es:di],0x07 inc di inc si loop @g ;The following calculations1arrive100and xor ax,ax mov cx,1 @f: add ax,cx inc cx cmp cx,100 jle @f ;The following calculations累加和的每个数位 xor cx,cx ;Set the segment base address of the stack segment mov ss,cx mov sp,cx mov bx,10 xor cx,cx @d: inc cx xor dx,dx div bx or dl,0x30 push dx cmp ax,0 jne @d ;The following shows the digits @a: pop dx mov [es:di],dl inc di mov byte [es:di],0x07 inc di loop @a jmp near $ times 510-($-$$) db 0 db 0x55,0xaa
For code segment 4, the part that shows "1+2+3+4+...+100=" in the first part is to follow the practice in code 2 above and use loop loop processing.
The part that deals with numbers below is a new way of processing. Here, after dividing the number by 10 in turn to get the number of each digit, add it to 0x00 (reason: ASCII display characters need to be) and then in the next loop, the stack is sequentially and processed so that it can be displayed.
Four: Call the 10h interrupt of BIOS to display characters
The above, whether it is the simplest way to mov, movbw, or the X- or stack-pressing method, it is inevitable to deal with each character circle separately. Here is a method of calling BIOS interrupts, which directly handles a string of characters, which is relatively simple and has high referenceability.
org 07c00h ; Tell the compiler to load the program to 7c00Where mov ax, cs mov ds, ax mov es, ax call DispStr ; Call the display string routine jmp $ ; Infinite loop DispStr: mov ax, BootMessage mov bp, ax ; es:bp = String address mov cx, 16 ; cx = String length mov ax, 01301h ; ah = 13, al = 01h mov bx, 000ch ; Page number is 0(bh = 0) Red letters on black background(bl = 0Ch,Highlight) mov dl, 0 int 10h ; 10h Number interruption ret BootMessage: db "Hello, OS world!" times 510-($-$$) db 0 ; Fill in the remaining space,Make the generated binary code exactly dw 0xaa55 ; End sign
The method here is to call the 10h interrupt of the BIOS to display "Hello,OS world!", where bp is the string address, cx is the string length, ah is the function number, al indicates that the cursor is placed at the end of the string, bx indicates that the page number is 0, and then the character display attribute is a black-based red character, dh is the line number, and dl is the column number (if no processing is done, the default dh and dl are all 0, that is, it is displayed in the 0th row and column 0). After the parameter setting is completed, the 10h interrupt is called to display the string.
Summary: The above four methods not only understand the display method through learning, but more importantly, they have a more understanding of assembly language. The above methods are convenient in actual operation. Most of them use direct calls to the 10h interrupt of the BIOS to operate.
The above are four methods of displaying characters in the screen area introduced by the editor to you. I hope it will be helpful to you!