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 ich

    MOV 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 😕


Anmelden zum Antworten