Dónde colocar las subrutinas de ensamblaje en el archivo del sector de arranque.
Tengo el siguiente sector de arranque escrito en nasm:
[org 0x7c00]
<p>my<em>print</em>function:
mov ah, 0x0e
int 0x10
ret</p>
<p><em>start:
mov al, 'A'
call my</em>print<em>function
call my</em>print_function</p>
<p>_boot:
jmp $
times 510-($-$$) db 0
dw 0xaa55
Lo compilo con nasm -f bin boot.asm -o boot.bin
y luego ejecuto qemu boot.bin
, pero solo veo un carácter siendo impreso, y es el carácter basura 'U'
, no 'A'
. Si cambio el orden de my_print_function
y _start
, funciona como se espera, pero la subrutina también se ejecuta una vez por sí sola sin que la llame, por lo que imprime 'A'
tres veces.
Normalmente, si estuviera escribiendo en ensamblador, simplemente definiría la función my_print_function
antes de la sección .text
, y colocaría global _start
en la sección .text
, pero aquí parece que eso no hace nada. ¿Cómo puedo definir y usar esta subrutina sin que se ejecute una vez adicional solo porque la defino?
davy.ai
El problema es que cuando colocas
my_print_function
sobre_start
en el código, se ejecuta en el momento de cargar el código mismo, porque está fuera de cualquier procedimiento que solo debería ejecutarse al llamar a una función.Para definir y utilizar adecuadamente una subrutina en un cargador de inicio como este, debes mover la subrutina debajo de la etiqueta
_start
y definirla utilizando una etiqueta con dos puntos (por ejemplo,my_print_function:
en lugar de solomy_print_function
). Luego, puedes llamar a la subrutina concall my_print_function
. Aquí está el código corregido:De esta manera, la etiqueta
_start
se ejecuta primero, seguida de las dos llamadas amy_print_function
. La etiqueta_boot
solo se ejecuta si el programa cae desde_start
y alcanza la instrucciónjmp $
.También ten en cuenta que no necesitas declarar la etiqueta
_start
como global en este caso, ya que es la primera etiqueta del archivo y se utilizará como el punto de entrada del programa de forma predeterminada.