0

Hello, I`m newcomer here. I know English medium so please be charitable for me.

I have a big problem with LGDT function in Assembler. I use TASM. I used a TD Debugger to show what is the problem with LGDT and I showed that when I execute a line of code where is LGDT command, then the program is finish.

Do you know what cause it?

Greetings.

1
Contributor
1
Reply
2
Views
6 Years
Discussion Span
Last Post by tomek1908
0

I would like also send you my program code:

comment	*
	Program sluzacy do przelaczania procesora do trybu chronionego
	i z powrotem
	*

ideal
P386

;----------------------------------------------------------------------------

STACK16_SIZE	=	100h		; rozmiar stosu dla trybu rzeczywistego
STACK32_SIZE	=	200h		; rozmiar stosu w trybie chronionym


;****************************************************************************

segment code16 para public use16	; w tym segmencie wszystko jest 16-bitowe
assume cs:code16, ds:code16		; dopasowanie kodu i danych

;----------------------------------------------------------------------------

stack16		db	STACK16_SIZE dup (?)	; Stos 16-bitowego trybu rzeczywistego
label	stack16_end	word

;----------------------------------------------------------------------------
; szybke i nieczyste wyjscie
; wejscie:	DS:DX - wskaznik na lancuch zakonczony znakiem '$' 
; wyjscie:	Trudno powiedziec, funkcja nigyd nie wraca :)

proc	err16exit
	mov	ah,9			; wybranie funkcji DOS-a drukujacej lancuch
	int	21h			; wypisanie komunikatu
	mov	ax,4cffh		; wyjscie z kodem powrotu 0ffh
	int	21h			; do widzenia...
endp	err16exit


;----------------------------------------------------------------------------
; ta procedura po prostu wypisuje wiadomosc zakonczona zerem na ekranie
; format: slowo x, slowo y, attribute bajt, string, 0
; wejscie:	DS:SI - wskaznik na lancuch

proc	write_msg
	push	ax si di es
	mov	ax,0b800h		; segment obrazu tekstowego 
	mov	es,ax			; pobranie go do ES
	mov	ax,[si+2]		; pobranie pozycji Y
	mov	di,160
	mul	di
	add	ax,[si]
	mov	di,ax
	mov	ah,[si+4]		; pobranie bajta atrybutow
	add	si,5
write_loop_pm:
	mov	al,[si]
	or	al,al			; koniec lancucha?
	jz	loop_end_pm
	inc	si
	mov	[es:di],ax
	inc	di
	inc	di
	jmp	write_loop_pm
loop_end_pm:
	pop	es di si ax
	ret
endp	write_msg

;----------------------------------------------------------------------------
; glowna procedura, tutaj jest punkt wejscia 

rm_msg		db	0,0,0,0,1fh,'Teraz w trybie rzeczywistym - nacisnij klawisz aby przelaczyc '
		db	'do trybu chronionego!',0
rm2_msg		db	0,0,3,0,1fh,'Z powrotem w trybie rzeczywistym - nacisnij klawisz aby wrocic '
		db	'do DOS-a!',0

;----------------------------------------------------------------------------

label global_descriptor_table fword	; tutaj rozpoczyna sie GDT

gdt_start	  dw		     gdt_size,0,0	     ; wart. dla GDT 
DeskryptorZerowy DW 	0h, 0h, 0h, 0h
DeskryptorDaneA DW	0FFFFh, 0h, 9200h, 0000h
DeskryptorDaneB DW	0FFFFh, 0h, 9200h, 0040h
DeskryptorEkranu DW	0F9Fh, 8000h, 920Bh, 0000h
DeskryptorKodA DW	0FFFFh, 0h, 9A00h, 0000h
DeskryptorKodB DW	0FFFFh, 0h, 9A00h, 0040h	

gdt_size=$-(offset DeskryptorZerowy)

;selektory - musza byc w takiej kolejnosci w jakiej sa deskryptory?
SelektorDaneA	EQU 08h
SelektorDaneB	EQU 10h
SelektorEkranu	EQU 18h
SelektorKodA	EQU 20h
SelektorKodB	EQU 28h


;----------------------------------------------------------------------------		
		
start16:
	mov	ax,cs		; ladowanie segmentu kodu do DS i ES
	mov	ds,ax
	mov	es,ax
	cli			; lepiej zablokowac przerwania podczas ustawiania
	mov	ss,ax		; SS i SP
	mov	sp,offset stack16_end
	sti			; odblokowanie przerwan

	;call	check_processor	; sprawdzenie czy procesor przynajmniej 80386
	;call	check_mode	; sprawdzenie czy pracujemy w trybie rzeczywistym

	mov bx, offset DeskryptorKodA
	mov	ax,code16	; pobranie segmentu kodu do AX
	movzx	eax,ax		; czyszczenie starszego slowa w EAX
	shl	eax,4		; stworzenie fizycznego adresu
	mov	[bx+2],ax ; zachowanie w deskryptorze
	shr	eax,8
	mov	[bx+4],ah
	
	mov bx, offset DeskryptorDaneA
	mov	ax,code16	; pobranie segmentu kodu do AX
	movzx	eax,ax		; czyszczenie starszego slowa w EAX
	shl	eax,4		; stworzenie fizycznego adresu
	mov	[bx+2],ax ; zachowanie w deskryptorze
	shr	eax,8
	mov	[bx+4],ah
	
	mov bx, offset DeskryptorKodB
	mov	ax,code32	; pobranie segmentu kodu do AX
	movzx	eax,ax		; czyszczenie starszego slowa w EAX
	shl	eax,4		; stworzenie fizycznego adresu
	mov	[bx+2],ax ; zachowanie w deskryptorze
	shr	eax,8
	mov	[bx+4],ah
	
	mov bx, offset DeskryptorDaneB
	mov	ax,code32	; pobranie segmentu kodu do AX
	movzx	eax,ax		; czyszczenie starszego slowa w EAX
	shl	eax,4		; stworzenie fizycznego adresu
	mov	[bx+2],ax ; zachowanie w deskryptorze
	shr	eax,8
	mov	[bx+4],ah

	mov	ax,code32	; pobranie 32-bitowego segmentu kodu do AX
	movzx	eax,ax		; czyszczenie starszej czesco eax
	shl	eax,4		; stworzenie fizycznego adresu
	add	eax,offset DeskryptorZerowy ; obliczenie fizycznego adresu GDT
	mov	[dword ds:gdt_start+2],eax

	mov	ax,3		; ustawienie trybu tekstowego 3, 
				; po prostu uzywane aby wyczyscic ekran
	int	10h		; 

	mov	si,offset rm_msg; wypisanie komunikatu trybu rzeczywitego
	call	write_msg

	;mov	si,offset rm2_msg	; wypisanie drugiego komunikatu
	;call	write_msg
	
	xor	ah,ah ; czekanie na klawisz
	int	16h

	cli			; blokada przerwan
	lgdt	[fword ds:global_descriptor_table]	; zaladowanie GDT
	mov	eax,cr0		; pobranie CR0 do EAX
	or	al,1		; ustawienie bitu trybu chronionego
	mov	cr0,eax		; po tej operacji jestesmy w trybie chronionym!
	db	0eah		; kod maszynowy far jump (do ustawienia CS poprawnie)
	dw	offset start32
	dw	SelektorKodB

exit16:				; z trybu chroninego wracamy tutaj
	mov	eax,cr0		; pobranie CR0 do EAX
	and	al,not 1	; czyszczenie bitu trybu chronionego
	mov	cr0,eax		; po tej operacji jestesmy z powrotem w
				; trybie rzeczywistym!
	;db	0eah
	;dw	offset flush_ipq
	;dw	SelektorKodA
flush_ipq:
	mov	ax,cs		; odtworzenie waznych rejestrow
	mov	ss,ax
	mov	sp,offset stack16_end
	mov	ds,ax
	mov	es,ax
	sti			; odblokowanie przerwan 

	mov	si,offset rm2_msg	; wypisanie drugiego komunikatu
	call	write_msg

	xor	ah,ah		; czekanie na klawisz 
	int	16h

	mov	ax,3		; czyscimy ekran jeszcze raz
	int	10h

	mov	ax,4c00h	; wszystko jest w porzadku, wychodzimy 
				; z kodem powrotu 0
	int	21h		; koniec...

;----------------------------------------------------------------------------

ends	code16

segment code32 para public use32	; ten segment zawiera wszystko 32-bitowe
assume cs:code32, ds:code32		; przypisanie kodu i dnych

stack32		db	STACK32_SIZE dup (?)	; 32-bitowy stos 
label	stack32_end	dword

pm_msg		db	0,0,1,0,1fh,'Teraz w trybie chronionym - wywolujemy Interrupt '
		db	'Handler!',0

start32:		; tutaj startujemy w trybie chronionym
	mov	ax,SelektorDaneB		; ladujemy potrzebne rejestry z wlasc.
	mov	ss,ax			; selektorami
	mov	esp,offset stack32_end	; rozmiar stosu
	mov	ds,ax
	mov	es,ax
	mov	fs,ax
	mov	gs,ax

mov ax, SelektorDaneB ;ustawiamy selektory na segmenty bo pracujemy juz w trybie chronionym
mov ds, ax

mov ax, SelektorEkranu
mov es,ax

	
		mov ecx, 1000 
		xor ebx,ebx 
		
;Wyczyszczenie ekranu
                ;mov     ah, 06h         ; funkcja karty grafiki przewijajaca
                                        ; linie fragmentu ekranu w gore
                ;mov     al, 0           ; liczba linii do przewiniecia -
                                        ; caly ekran (czyszczenie ekranu)
                ;mov     bh, 07          ; atrybut pustych linii - jasnoszary
                ;mov     ch, 0           ; wiersz lewego gornego rogu
                                        ; przewijanego framgmentu - lewy
                                        ; gorny rog ekranu
                ;mov     cl, 0           ; kolumna lewego gornego rogu
                                        ; przewijanego framgmentu - lewy
                                        ; gorny rog ekranu
                ;mov     dh, 24          ; wiersz prawego dolnego rogu
                                        ; przewijanego framgmentu - prawy
                                        ; dolny rog ekranu
                ;mov     dl, 79          ; kolumna prawego dolnego rogu
                                        ; przewijanego framgmentu - prawy
                                        ; dolny rog ekranu
                ;int     10h             ; wywolanie przerwania karty grafiki

;teraz powinien sie wyswietlic ten tekst
		xor ebx,ebx
		xor ecx, ecx
; Ustawienie kursora na poczatku ekranu
                mov     ah, 02h         ; funkcja karty grafiki ustawiajaca
                                        ; kursor na nowej pozycji
                mov     bh, 0           ; numer strony trybu graficznego
                mov     dh, 0           ; wiersz nowej pozycji kursora - lewy
                                        ; gorny rog ekranu
                mov     dl, 0           ; kolumna nowej pozycji kursora -
                                        ; lewy gorny rog ekranu
                int     10h             ; wywolanie przerwania karty grafiki

; Wyswietlenie napisu w miejscu ustawienia kursora
                mov     ah, 09h         ; funkcja systemowa wyswietlajaca
                                        ; napis (zakonczony znakiem '$')
                mov     dx, OFFSET pm_msg ; adres napisu do wyswietlenia
                                         ; (przesuniecie w segmencie danych)
                int     21h             ; wywolanie przerwania systemowego
koniec:
	
	;mov	esi,offset pm_msg; wypisanie komunikatu trybu rzeczywitego
	;call	write_msg_pm
	
	;call	main			; teraz, wszystko jest ustawione:
					; wywolujemy main!

	;db	0eah	; kod maszynowy dalekiego skoku	
			; kiedy wychodzimy z main, i wracamy 
	;dw	offset exit16
	;dw	SelektorKodA	; do trybu rzeczywistego

;----------------------------------------------------------------------------
; translacja dla trybu chronionego procedury write_msg
; wejscie:	DS:ESI - wskaznik do lancucha formatowanego

proc	write_msg_pm
	push	ax esi edi es
	mov	ax,SelektorEkranu		; w trybie chronionym musimy uzywac
					; bezposredniego adresu pamieci
					; aby zaadresowac ekran
	mov	es,ax
	movzx	di,[esi+2]		; pobranie pozycji Y 
	imul	edi,160
	add	di,[esi]		; dodanie pozycji X 
	add	di,[esi]
	add	edi,0b8000h		; fizyczny adres tekstu na ekranie
	mov	ah,[esi+4]		; pobranie bajta atrybutow
	add	esi,5
write_loop:
	mov	al,[esi]
	or	al,al			; koniec lancucha?
	jz	loop_end
	inc	esi
	mov	[es:edi],ax
	inc	edi
	inc	edi
	jmp	write_loop
loop_end:
	pop	es edi esi ax
	ret
endp	write_msg_pm

;----------------------------------------------------------------------------
; glowna procedura dla trybu chronionego

main:
	mov	esi,offset pm_msg	; po prostu wyswietlamy komunikat...
	call	write_msg_pm
	int	0			; ...wywolujemy przykladowe przerwanie...
	ret				; ...i powrot

;----------------------------------------------------------------------------

ends	code32

;****************************************************************************

end start16
This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.