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?
CodePudding user response:
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.