Dices "inicia directamente en Windows" así que supongo que estás usando una PC física. Nota futura para hacer: ¡Siempre use un emulador para el desarrollo! Es simplemente más fácil. Me gusta Bochs para OSDeving porque tiene buenas funciones de depuración. Ahora, sobre la posible solución.
Hay muchas BIOS defectuosas que rompen las especificaciones informales de la PC IBM para la dirección de carga 0x7C00.
Esto puede causar muchos problemas con las direcciones de memoria y cosas así durante el montaje. Así que al principio parece a esto:
[BITS 16] ;tell the assembler that its a 16 bit code
[ORG 0x7C00] ;this tells the assembler where the code will be loaded at when it runs on your machine. It uses this to compute the absolute addresses of labels and such.
jmp word 0:flush ;#FAR jump so that you set CS to 0. (the first argument is what segment to jump to. The argument(after the `:`) is what offset to jump to)
;# Without the far jmp, CS could be `0x7C0` or something similar, which will means that where the assembler thinks the code is loaded and where your computer loaded the code is different. Which in turn messes up the absolute addresses of labels.
flush: ;#We go to here, but we do it ABSOLUTE. So with this, we can reset the segment and offset of where our code is loaded.
mov BP,0 ;#use BP as a temp register
mov DS,BP ;#can not assign segment registers a literal number. You have to assign to a register first.
mov ES,BP ;#do the same here too
;#without setting DS and ES, they could have been loaded with the old 0x7C0, which would mess up absolute address calculations for data.
Sede, alguna carga en 0x07C0:0000
y la mayor parte de la carga (y su correcta considerado) a 0x0000:7C00
. Es la misma dirección plana, pero las diferentes configuraciones de segmento realmente pueden arruinar direcciones de memoria absolutas. Así que vamos a eliminar la "magia" del ensamblador y ver lo que parece (nota no garantizo direcciones para ser completamente correcta con esto. No sé el tamaño de todos los códigos de operación)
jmp word 0:0x7C04 ;# 0x7C04 is the address of the `flush` label
...
por lo , saltamos a una dirección absoluta.
Ahora bien.¿Qué pasa cuando no hacemos esto?
tomar este programa, por ejemplo:
mov ax,[mydata]
hlt
mydata: dw 500 ;#just some data
Esto desmonta a algo así como
mov ax,[0x7C06]
Oh, así que utiliza el direccionamiento absoluto, así que ¿cómo puede ir mal? Bueno, ¿y si DS es realmente 0x7C0
? entonces, en lugar de obtener el ensamblador esperado 0:0x7C06
obtendrá 0x7C0:0x7C06
que son no la misma dirección plana.
Espero que esto lo ayude a comprender. Sin embargo, es realmente un tema complicado y requiere un tiempo de programación de bajo nivel para comprenderlo por completo.
Hola, gracias por la respuesta. Lamentablemente, su código no es sintaxis correcto en NASM. Me dice que hay una discrepancia en el tamaño del operando (??) en la línea que comienza con "jmp FAR 0x0000 ...". Aún así, gracias por agradecer la sugerencia del emulador. – DarkOwl
@Newbie sí, mi sintaxis de NASM es un poco oxidado, intento 'jmp word 0: begin' – Earlz
Acabo de instalar Bochs y arranqué el código de tutorial original en él. ¡El código de cada tutorial ahora funciona! La pregunta es, ¿es mi BIOS phyiscal que no es estándar, o es el código? (¿Seguro que todas las BIOS compatibles con x86 deben cumplir con los mismos estándares?) De todos modos, intentaré su enmienda en el BIOS físico de mi PC. – DarkOwl