Si dice "avvia direttamente in Windows", quindi presumo che si stia utilizzando un PC fisico. Nota futura da fare: usa sempre un emulatore per lo sviluppo! È solo più facile Mi piace Bochs per OSDeving perché ha delle belle funzionalità di debug. Ora, sulla possibile soluzione.
Esistono numerosi BIOS buggy che interrompono le specifiche informali del PC IBM per l'indirizzo di caricamento 0x7C00.
Questo può dare un sacco di problemi con gli indirizzi di memoria e così ogni volta che si sta assemblando. Quindi, fare l'inizio simile a questa:
[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, alcuni carico a 0x07C0:0000
e la maggior parte del carico (e la sua ritenuto corretto) a 0x0000:7C00
. È lo stesso indirizzo piatto, ma le diverse impostazioni del segmento possono rovinare gli indirizzi di memoria assoluti. Quindi cerchiamo di rimuovere la "magia" del assembler e vediamo come si presenta (nota non garantisco indirizzi per essere completamente corrette in questo. Non so le dimensioni di tutti i codici operativi)
jmp word 0:0x7C04 ;# 0x7C04 is the address of the `flush` label
...
Così , passiamo a un indirizzo assoluto.
Ora quindi.Cosa succede quando non lo facciamo?
prendere questo programma, ad esempio:
mov ax,[mydata]
hlt
mydata: dw 500 ;#just some data
Questo smonta a qualcosa di simile
mov ax,[0x7C06]
Oh, beh utilizza indirizzamento assoluto, così come potrebbe andare storto? Bene, cosa succede se DS è in realtà 0x7C0
? quindi invece di ottenere l'assembler previsto 0:0x7C06
otterrà 0x7C0:0x7C06
che sono non lo stesso indirizzo piatto.
Spero che questo ti aiuti a capire. È un argomento davvero complicato e richiede un po 'di programmazione di basso livello per comprendere appieno.
Ciao, grazie per la risposta. Sfortunatamente il tuo codice non è sintatticamente corretto in NASM. Mi dice che c'è una mancata corrispondenza nella dimensione dell'operando (??) sulla riga che inizia con "jmp FAR 0x0000 ...". Ancora, grazie per il suggerimento dell'emulatore. – DarkOwl
@Newbie yea la mia sintassi NASM è un po 'arrugginita prova 'jmp word 0: begin' – Earlz
Appena installato Bochs e avviato il codice tutorial originale in esso. La forma del codice ogni esercitazione ora funziona! La domanda è, è il mio BIOS phyiscal che è non standard, o è il codice? (Sicuramente tutti i BIOS compatibili x86 devono rispettare gli stessi standard ???) Proverò comunque il tuo ammendamento sul BIOS fisico del mio PC. – DarkOwl