En este artículo aprenderemos como la BIOS organiza la RAM de forma interna y como localizar direcciones de memoria de variables de nuestro programa en ASM.
Antes de comenzar es recomendable que leas estos artículos anteriores:
Cuando la BIOS carga el boot sector la RAM queda dispuesta del siguiente modo.
Como podemos ver la dirección de memoria en la que comienza el boot sector es 0x7c00, si definimos una variable en nuestro código y posteriormente la utilizamos en alguna operación debemos averiguar su localización, esto lo conseguimos sumándole a la dirección base la dirección relativa de la variable, es decir 0x7c00 + N.
Este ejemplo continúa con el anterior pero esta vez pintamos el valor de la variable.
mov ah, 0x0e; tty mode
mov bx, the_secret; get relative address of the_secret
add bx, 0x7c00; absolute address = the_secret relative address + boot sector base address
mov al, [bx]; set al value to absolute address
int 0x10
jmp $ ; infinite loop
the_secret:
db "X"
; zero padding and magic bios number
times 510-($-$$) db 0
dw 0xaa55
Generamos la imagen:
La cargamos en qemu:
SeaBIOS (version rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org)
iPXE (http://ipxe.org) 00:03.0 C980 PCI2.10 PnP PMM+07F91410+07EF1410 C980
Booting from Hard Disk...
X
Podemos evitar el tener que calcular la dirección absoluta si le indicamos a nasm la dirección base directamente:
[org 0x7c00] ; tell the assembler that our base address is bootsector address
mov ah, 0x0e; tty mode
mov bx, the_secret;
mov al, [bx]
int 0x10
jmp $ ; infinite loop
the_secret:
db "X"
; zero padding and magic bios number
times 510-($-$$) db 0
dw 0xaa55
Generamos la imagen:
La cargamos en qemu:
SeaBIOS (version rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org)
iPXE (http://ipxe.org) 00:03.0 C980 PCI2.10 PnP PMM+07F91410+07EF1410 C980
Booting from Hard Disk...
X