Home > Blockchain >  How does popa and pusha actually works?
How does popa and pusha actually works?

Time:01-24

I am attempting to write a simple OS from scrath, but I have stumbled into a problem. I wrote a simple procedure that runs through a string and prints it on the screen.

print_string:
    pusha
    cmp byte[bx], 0    
    je exit             
    mov ah, 0x0e        
    mov al, [bx]        
    int 0x10            
    inc bx              
    jmp print_string    
    
    exit: 
        mov ah, 0x0e       
        mov al, 13          
        int 0x10            
        mov al, 10          
        int 0x10            
        popa
        ret                 

And I am including it on the main file.

[org 0x7c00]              

mov bx, hello               
call print_string           
mov bx, hi                 
call print_string          
jmp $                       

%include "print_string.s"   
hello:                  
    db "Hello, World!",0     
hi:
    db "This is a test.",0

times 510-($-$$) db 0       
dw 0xaa55                   

But for some reason, instead of printing Hello, World! This is a test. it just prints Hello World!

When I remove the pusha and popa from print_string.s and place it on the main file like this:

[org 0x7c00]              

mov bx, hello    
 
pusha          
call print_string 
popa      
    
mov bx, hi   

pusha               
call print_string   
popa 
       
jmp $                       

%include "print_string.s"   
hello:                  
    db "Hello, World!",0     
hi:
    db "This is a test.",0

times 510-($-$$) db 0       
dw 0xaa55                   

It works just fine. Why?

CodePudding user response:

print_string is called in the loop, on each iteration is does pusha. But there is only one popa instruction for multiple pusha. A fix:

print_string:
    pusha
next_char:
    mov al, [bx]        
    or al, al
    je exit             
    mov ah, 0x0e        
    int 0x10            
    inc bx              
    jmp next_char   
  • Related