Der Quantensprung ( Sprung in den Protected Mode / Sprung über die 16-Bit Queue )
-
Halli Hallo.
Ich hab ein etwas nerviges Problem.
Und zwar will ich über die 16-Bit Queue springen, aber irgendwie springt
dieser einfach in's Nirvana.Ich paste mal den Code:
sector1.asm:
org 0h jmp 0x07c0:boot_sec1_main include "video.asm" boot_sec1_main: ; Init Stack mov ax, cs mov ss, ax mov sp, 0 mov [boot_sec1_drv], dl ; Save drive num ; Init Data Segment mov ds, ax ; Load Sector 2 mov ax, 0xb800 mov es, ax mov si, msg_sec1_read call video_print_message call boot_read_sec2 ; Jump to Stage 2 mov ax, 0xb800 mov es, ax mov si, msg_sec1_enter call video_print_message jmp 0x1000:0x0 boot_reset_drv: mov ah, 0h mov dl, [boot_sec1_drv] int 13h jc boot_reset_drv ret boot_read_sec2: mov ax, 0x1000 mov es, ax ; where to write to es:bx xor cx, cx ; cx = 0 mov bx, cx ; bx = 0 read: mov ah, byte [msg_sec1_read_m] mov al, byte [msg_sec1_count] cmp al, ah ; try to read 8 times, else the sector isnt present or the disk is mov al, 0 ; corrupt je chk ; increment read num add [msg_sec1_count], 1 call boot_reset_drv mov ah, 02h ; fnc mov al, 5 ; num sectors mov cl, 2 ; sector num mov dh, 0 ; head num mov dl, [boot_sec1_drv] ; drive num int 13h jc read ; check if all went fine or if ; a disk is corrupt or a sector is missing chk: mov si, msg_sec1_fail cmp al, 5 jne boot_error ret boot_error: ; error string set? cmp si, 0 jz boot_error_ret ; print error string mov ax, 0xb800 mov es, ax call video_print_message ; Print Message mov ah, 0h int 16h ; Wait for a Key jmp 0xffff:0 ; Reboot ; no string set boot_error_ret: ret boot_sec1_drv db 0 ; drive to read from msg_sec1_count db 0 ; sector read runs msg_sec1_read_m db 8 ; max amount of runs msg_sec1_read db "Stage 1: Reading Sector 2", 13, 10, 0 msg_sec1_chk_f db "Stage 1: Missing Stage 2", 13, 10, "Press Any Key to Reboot", 0 msg_sec1_enter db "Stage 1: Entering Stage 2", 13, 10, 0 msg_sec1_fail db "Stage 1: Failed Reading Sector 2 (Missing/Corrupt Disk?)", 13, 10, "Press Any Key to Reboot", 0 times 510-($-$$) db 0 db 0x55 db 0xAAsector2.asm:
org 0h jmp 1000h:boot_sec2_main include "video.asm" use16 boot_sec2_main: mov eax, cs mov ds, ax mov ax, 0xb800 mov es, ax mov al, 2 call video_set_pos_y mov si, msg_sec2_gdt call video_print_message ; Disable Interrupts since there is no IDT cli ; Setup Descr. Address & load GDT call boot_sec2_load_gdt mov ax, 0xb800 mov es, ax mov si, msg_sec2_pm call video_print_message ; Enter Protected Mode mov eax, cr0 or eax, 1 mov cr0, eax ; Far Jump to flush the queue db 0xea dw boot_sec2_pm dw 0x8 nop use16 boot_sec2_load_gdt: mov eax, cs shl eax, 4 ; segment mov word [data_descr+2], ax mov word [code_descr+2], ax shr eax, 16 ; offset mov byte [data_descr+4], al mov byte [code_descr+4], al lgdt [gdt] ; laden ret use32 boot_sec2_pm: mov ax, 1100b ; 2 descr, ring 0, gdt mov ds, ax mov ss, ax mov esp, 0 mov ax, 100000b ; 4 descr, ring 0, gdt mov es, ax mov si, msg_sec2_pm_r call video_print_message jmp $ msg_sec2_gdt db "Stage 2: Setting up GDT", 13, 10, 0 msg_sec2_pm db "Stage 2: Entering Protected Mode", 13, 10, 0 msg_sec2_pm_r db "Stage 2: Hello World from Protected Mode", 13, 10, 0 gdt_begin: null_descr: dd 0, 0 code_descr: dw 0xFFFF ;size dw 0 ;addr db 0 ;addr db 10011010b ;im speicher, ring0, speicher descr, code read&exe, unbenutzt db 11001111b ;4 gb, 80386, reserviert, unbesetzt, größe db 0 ;addr data_descr: dw 0xFFFF ;size dw 0 ;addr db 0 ;addr db 10010110b ;im speicher, ring0, speicher descr, data expand read&write, unbenutzt db 11001111b ;4 gb, 80386, reserviert, unbesetzt, größe db 0 ;addr video_descr: dw 4000 dw 0x8000 db 0xB db 10010010b db 00000000b db 0 gdt: dw (gdt-gdt_begin)-1 dd gdt_beginSoweit sogut.
Sektor 1 funktioniert wunderbar.
Im 2. Sektor haperts ab "db 0xEA [..]", also dem Jump-Befehl.Habt ihr eine Ahnung, ich weiß irgendwie nicht mehr so ganz weiter.
-
Spaetestens bei Zeile 67 wird dein Code crashen, weil es einen Stack-Overflow gibt. Merke: Stack waechst nach unten!
Weiter werden in 32Bit-Code auch standardmaessig 32Bit-Register zur Adressierung
benutzt. Du musst also entsprechend immer esi, bzw. edi komplett zur Adressierung setzen (oder zumindest sicher gehen, dass die oberen 16Bit auch wirklich 0 sind).In Zeile 58 setzt du die Selektoren falsch. Es muss 10h fuer den Dataselektor und 18h fuer den video-deskriptor sein.
Das war erstmal so weit alles.