Mówisz "bootuj prosto do Windowsa", więc zakładam, że używasz fizycznego komputera. Przyszłe uwagi: Zawsze używaj emulatora do programowania! To po prostu łatwiejsze. Lubię Bochs dla OSDeving, ponieważ ma on dobre funkcje debugowania. Teraz przejdź do możliwego rozwiązania.
Istnieje wiele błędnych BIOSów, które łamią nieformalne specyfikacje komputera IBM dla adresu ładowania 0x7C00.
Może to powodować wiele problemów z adresami pamięci i takimi, ilekroć się montuje. Tak uczynić początek wyglądać następująco:
[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.
See, pewne obciążenie przy 0x07C0:0000
i największe obciążenia (i jej uznać wypada) przy 0x0000:7C00
. Jest to ten sam adres płaski, ale różne ustawienia segmentu mogą naprawdę zepsuć adresy pamięci absolutnej. Warto więc usunąć „magii” w asemblerze i zobaczyć jak to wygląda (należy pamiętać, że nie gwarantują adresy być całkowicie poprawne z tym. Nie wiem, rozmiar wszystkich rozkazy)
jmp word 0:0x7C04 ;# 0x7C04 is the address of the `flush` label
...
tak , skaczemy do absolutnego adresu.
Teraz.Co się dzieje, gdy tego nie robimy?
wziąć ten program na przykład:
mov ax,[mydata]
hlt
mydata: dw 500 ;#just some data
ten demontuje się do czegoś podobnego
mov ax,[0x7C06]
Och, dobrze wykorzystuje adresowanie bezwzględne, tak jak to może się nie udać? A co, jeśli DS faktycznie jest 0x7C0
? wtedy zamiast oczekiwać, że asembler będzie oczekiwał 0:0x7C06
, otrzyma on 0x7C0:0x7C06
, który nie ma takiego samego płaskiego adresu.
Mam nadzieję, że pomoże to zrozumieć. To naprawdę skomplikowany temat, który zajmuje trochę czasu w programowaniu na niskim poziomie, aby w pełni go zrozumieć.
Cześć, dziękuję za odpowiedź. Niestety Twój kod nie jest poprawny pod względem składni w NASM. Mówi mi, że istnieje niedopasowanie wielkości operandu (??) na początku linii "jmp FAR 0x0000 ...". Mimo to, dziękuję za wskazówkę dla emulatora. – DarkOwl
@Newbie tak, moja składnia NASM jest nieco zardzewiała spróbuj 'jmp word 0: begin' – Earlz
Właśnie zainstalowałem Bochs i załadowałem oryginalny kod samouczka do niego. Kod każdego tutoriala działa teraz! Pytanie brzmi, czy to mój BIOS phyiscal jest niestandardowy, czy też jest to kod? (Z pewnością wszystkie BIOSy zgodne z x86 muszą być zgodne z tymi samymi standardami ???). Spróbuję jednak poprawek na fizycznym BIOSie mojego komputera. – DarkOwl