SoFunction
Updated on 2025-03-04

Assembly language Four ways to display characters in the screen area (recommended)

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!