Search code examples
assemblyx86intel-syntax

Intel x86 asm print string function


I attempted to write a print string function;

 45 ; the address is stored in si                                                                                       
 46 print_string:                                                                   
 47     pusha                                                                       
 48     ; load character from si                                                    
 49     mov al, [si]                                                                
 50     cmp al, 0x00                                                                
 51     jz print_string_end                                                         
 52     call print_char ; print the char using the print_char function              
 53     inc si ; increment the string printing index si                             
 54 print_string_end:                                                               
 55     popa                                                                        
 56     ret                                                                         
 57                                                                                 
 58 ; print function: print a single character                                      
 59 ; the character is stored in al                                                 
 60 print_char:                                                                     
 61     pusha                                                                       
 62     mov ah, 0x0e                                                                
 63     int 0x16                                                                    
 64     popa            ; don't know what registers int 0x16 modifies               
 65     ret                                                                         
 66                                                                                 
 67 mystring:                                                                       
 68 db "loading operating system",0x00  

This assembles and runs. However before I changed to using si for the address of the current character to print, I was using the register dx. For some reason changing from si to dx causes the following nasm error:

bootsector.asm:49: error: invalid effective address

Why doesn't mov al, [dx] work, but mov al, [si] does?


Solution

  • The 16-bit 8086 only supported bx and bp as base registers, and si and di as index registers. You can use both for modes like [bx+si], or omit one to get [bx] or [si], but dx is never usable in an effective address. Since 16-bit real mode is compatible with the 8086, it has the same restriction.

    See https://www.ic.unicamp.br/~celio/mc404s2-03/addr_modes/intel_addr.html for a complete rundown of 8086 addressing modes.