Prozessorfehler mit MOV Befehl im P-Mode (NASM)
-
Hallo und Guten Abend,
Ich komme wieder mal nicht weiter...
Mein Programm macht nichts weiter als vom R-Mode in den P-Mode und zurück
zu wechseln.Am Anfang und wieder zurück im R-Mode, lass ich mir den Wert von CS, also
vor und nach dem Wechsel anzeigen, damit ich sehe ob ich im richtigen
Segment lande... hatte da Anfangs auch etwas Probleme.Mein Frage ist nun diese:
Wieso hängt sich der Prozessor auf wenn ichMOV BX, 2511
in Zeile 65 auskommentiere???
ORG 100h start: ;alle Register löschen xor eax, eax xor ebx, ebx xor ecx,ecx xor edx, edx xor edi, edi xor esi, esi mov ax, cs ;CS nach AX call PRINT ;Wert von CS anzeigen (DOS) mov ax, cs mov word [cs:rmode_cs], ax mov bx, 16 mul bx ;DX:AX = CS * 16 mov bx, CODE ;Zeiger auf die Deskriptoren mov di, DATEN ;CODE, DATEN und REAL Segment für Rücksprung mov si, REAL ;Die unteresten 2 Byte von "Basis" setzen (AX) mov word [ds:bx + 2], ax mov word [ds:di + 2], ax mov word [ds:si + 2], ax ;Das 3. Byte von Basis setzen (DL) mov byte [ds:bx + 4], dl mov byte [ds:di + 4], dl mov byte [ds:si + 4], dl xor eax, eax mov ax, cs shl eax, 4 push eax add eax, gdttabelle mov [gdt_base], eax ;Basis der GDT eintragen pop eax add eax, start_idt mov [idt_base], eax ;Basis der IDT eintragen (noch nicht vorhanden) lgdt [GDT] ;GDT laden cli ;Interrupts aus mov eax, cr0 or ax, 1 mov cr0, eax ;In den P-Mode wechseln db 0eah ;JMP zu Adresse "pmode" dw pmode dw 0x8 pmode: ;Selectoren setzen mov ax, 16 mov ds, ax mov ax, 32 mov es, ax ;mov bx, 2511 backtodos: ;Selektor für RM Segmente setzen mov ax, 24 mov ds, ax mov es, ax mov eax, cr0 dec ax mov cr0, eax ;Prozessor in den RM schalten db 0eah dw rmode rmode_cs dw 0 ;JMP zu Adresse "rmode" rmode: mov ax, cs ;Wert von CS nach AX call PRINT ;Wert anzeigen (DOS) sti mov ax, 04c00h int 21h ;Programm beenden testzahl dw 2511d ;%include "funktionen.inc" ;Die Segmente haben alle Byte-Granularität = max. 1MB ;DB Bit gesetzt für 32Bit Operandengröße gdttabelle: dd 0 dd 0 CODE: dw 0xFFFF dw 0 ; wird zur Laufzeit eingetragen db 0 ; wird zur Laufzeit eingetragen db 10011010b db 01000000b ;Nur DB Bit gesetzt db 0 DATEN: dw 0xFFFF dw 0 ; wird zur Laufzeit eingetragen db 0 ; wird zur Laufzeit eingetragen db 10010010b db 01000000b db 0 REAL: dw 0xFFFF dw 0 ; wird zur Laufzeit eingetragen db 0 ; wird zur Laufzeit eingetragen db 10010010b db 00000000b db 0h VIDEO: dw 0xFFFF dw 0x8000 db 0xB db 10010010b db 01000000b db 0 GDT: gdt_limit dw 40 ;5 * 8 = 40 Byte gdt_base dd 0 ;wird in Zeile 39 eingetragen
**Assemblieren mit
nasm -O32 os_1.asm -o os_1.com pause
**
Wofür braucht man die Anweisung [Bits 16] oder [Bits 32]?
Die 32Bit Register kann man ja auch ohne diese Anweisung nutzen, da der 286
nicht als CPU Type festgelegt ist.Kann man mit [Bits 16] nur 16Bit Berechnungen durchführen, also auch nur 16 Bit
Adressieren im Speicher?Vielleicht hat hier ja noch jemand ein paar warme Worte für mich.
Ich geh erstmal was essen, mir qualmt der Kopf
Gruß, Nicky
PS: Ich weiß das manche Berechnung nicht "sinnvoll" sind, aber wichtig ist mir
erstmal das es läuft
-
Dieser Thread wurde von Moderator/in Erhard Henkes aus dem Forum Projekt: OS-Development in das Forum Assembler verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Hallo nochmal,
ich habe noch ein seltsames Verhalten entdeckt.
Nach dem Sprung in den PMode werden die Segmentregister mit ihren Werten
aus der GDT geladen (Zeile 20 - 25)Jedoch werden nur für DS und ES die Werte 24 eingetragen.
FS hat den Wert 0!
Wenn ich die unsinnige Zeile 24 löschen, bekommt auch FS den Wert 24.Ab Zeile 52 lasse ich mir diese Werte anzeigen.
; Teilauschnitt lgdt [GDT] ;GDT laden cli ;Interrupts aus mov eax, cr0 or ax, 1 mov cr0, eax ;In den P-Mode wechseln ; db 0eah ;JMP zu Adresse "pmode" ; dw pmode ; dw 0x8 jmp 0x8:pmode [bits 32] pmode: ;Selectoren setzen mov ax, 24d mov ds, ax mov es, ax mov ax, 24d mov fs, ax backtodos: ;Selektor für RM Segmente setzen mov ax, 24 mov ds, ax mov es, ax mov eax, cr0 dec ax mov cr0, eax ;Prozessor in den RM schalten db 0eah dw rmode rmode_cs dw 0 ;JMP zu Adresse "rmode" [bits 16] rmode: xor eax, eax mov ax, fs call PRINT xor eax, eax mov ax, [testzahl] call PRINT xor eax, eax mov ax, cs ;Wert von Var testzahl nach AX call PRINT ;Wert anzeigen (DOS) sti mov ax, 04c00h int 21h ;Programm beenden
Hat vielleicht hier jemand eine Ahnung woran das liegen könnte?
Ich kann somit nicht verschiedene Segmentregister mit verschiedenen Deskriptoren laden.Testsystem: Virtual PC auf Win7-64, virt. OS DOS Modus von Win98SE
Nicky