I want to test entering protected mode and returning
to real mode,but when I run program,my PC always
restart,Why does my PC restart,and how to correct it,
Look:
jump16 macro selector,offsetv
db 0eah ;jmp
dw offsetv ;2 bytes offset address
dw selector
endm
jump32 macro selector,offsetv
db 0eah
dd offsetv ;4 bytes offset address
dw selector
endm
;
descriptor struc
limitl dw 0
basel dw 0
basem db 0
attributes dw 0
baseh db 0
descriptor ends
;
pdesc struc
limit dw 0
base dd 0
pdesc ends
.386P
;---------------------------------
dseg segment use16
gdt label byte
dummy descriptor <>
code32_sel = 08h
code32 descriptor <0ffffh,,,4098h,>
gdtlen = $-gdt
;
vgdtr pdesc <gdtlen-1,>
dseg ends
;----------------------
;
cseg1 segment use16
assume cs:cseg1, ds:dseg
start:
mov ax,dseg
mov ds,ax
;
mov bx,16
mul bx
add ax,offset gdt
adc dx,0
mov word ptr vgdtr.base,ax
mov word ptr vgdtr.base+2,dx
;
mov ax,cseg2
mul bx
mov code32.basel,ax
mov code32.basem,dl
mov code32.baseh,dh
;
lgdt fword ptr vgdtr
;
cli
call ea20
;
mov eax,cr0
or eax,1
mov cr0,eax
;Enter protected mode
jump32 <code32_sel>,<offset spm32>
;
toreal:
call da20
sti
mov ah,4ch
int 21h
;
;
ea20 proc
push ax
in al,92h
or al,2
out 92h,al
pop ax
ret
ea20 endp
;
;
da20 proc
push ax
in al,92h
and al,0fdh ;0fdh=not 20h
out 92h,al
pop ax
ret
da20 endp
cseg1 ends
;---------------------------------
cseg2 segment use32
assume cs:cseg2
spm32:
mov eax,cr0
and eax,0fffffffeh
mov cr0,eax
;Return to real mode
jump16 <seg toreal>,<offset toreal>
;
cseg2 ends
;--------------------------
end start
leetow2003,
You'll have to find a way to analyze your programs yourself and detect why they don't work as expected.
If you want to learn, it's not a good strategy just to post your programs and expect others to find the errors.
Good strategies are:
- find a debugger which allows you to step through your mode-switching stuff. Have a look at Bochs!
- add "display" code to your program, which works in both real- and protected-mode. You should consider to access the text-mode screen at B800:0000 directly.
That said, in your program, your macro jump32 is faulty. How is the cpu to know that you want a 32--bit jump there? Make yourself familiar with the 0x66 prefix!
I am a novice,so I hope you can help me.
who could give me an example,the function of this example
only switch two modes,that it enters in 32-bit protected mode form real
mode,and then return back to real mode.Thank you very much.
Quote from: leetow2003, November 25, 2010, at 01:11:34 PMI am a novice,so I hope you can help me.
leetow2003,
I would like to underline japheth's statement. Moreover, for a novice, Protected Mode isn't the right playground, because system programming (that's what we speaking about) is really complicated stuff.
Quote from: leetow2003, November 25, 2010, at 01:11:34 PMwho could give me an example...
That technique isn't really necessary, because normal program termination via INT 21h is good enough. The only example that I have is 15 year old code for PowerBASIC. So, you must be familiar with PB 3.5 and TASM 4.1 (assembly language part). You can download the application from the PB site.
To your posted code: Another alternative as debugger is DEBUGX. It's a well written and good maintained tool; you can download it here: http://www.japheth.de/. Trace step by step through the code and you'll learn a lot.
Gunther
I am sorry,maybe waht I said was ambiguous.In fact I have
learned 8088 for a long time,but I learned 80386 not long ago,
so I am not familiar with protected mode,and I am interested
in it,so I asked some questions about it.I have downloaded
the tool debugx,but I find:for the same example,I compiled
it using masm 5.1 and tasm 3.0 respectively,and debugged the
exe file using debugx and debug32 respectively,a few instructions
aren't alike after unassemble.At last I compiled it using tasm 4.1,
but system prompt there are a lack of files,such as DPMI16BI.ovl,
DPMILOAD.exe,and so on.
I want to know what software you compile 80386 codes,and what files
you need.
Thank you very much.
Quote from: leetow2003 on November 26, 2010, 05:55:27 AM
and debugged the
exe file using debugx and debug32 respectively,a few instructions
aren't alike after unassemble.
Obviously.
Quote
At last I compiled it using tasm 4.1,
but system prompt there are a lack of files,such as DPMI16BI.ovl,
DPMILOAD.exe,and so on.
So you thought that you can solve the problem by using another assembler?
It might sound a bit offending, but that is very unwise IMO.
Instead you should have used your brain and learnt the intel JMP instruction.
I also used DEBUGX with your program. It tells:
D:\Test>debugx code303.exe
-u
14A4:0000 B8A214 MOV AX,14A2
14A4:0003 8ED8 MOV DS,AX
14A4:0005 BB1000 MOV BX,0010
14A4:0008 F7E3 MUL BX
14A4:000A 050000 ADD AX,0000
14A4:000D 83D200 ADC DX,+00
14A4:0010 A31200 MOV [0012],AX
14A4:0013 89161400 MOV [0014],DX
14A4:0017 B8AA14 MOV AX,14AA
14A4:001A F7E3 MUL BX
14A4:001C A30A00 MOV [000A],AX
14A4:001F 88160C00 MOV [000C],DL
-u
14A4:0023 88360F00 MOV [000F],DH
14A4:0027 0F01161000 LGDT [0010]
14A4:002C FA CLI
14A4:002D E81900 CALL 0049
14A4:0030 0F20C0 MOV EAX,CR0
14A4:0033 6683C801 OR EAX,+01
14A4:0037 0F22C0 MOV CR0,EAX
14A4:003A EA00000000 JMP 0000:0000
14A4:003F 0800 OR [BX+SI],AL
14A4:0041 E80E00 CALL 0052
-
and I can instantly see - with one glance - the problem: JMP 0000:0000. And no, it's NOT the fault of the assembler or DEBUGX, it's a simple error in your program.
leetow2003,
as japheth pointed out: there is at least one simple error in your program. It's easy to switch into 32 bit Protected Mode:
cli ;disable interrupts
mov eax,cr0 ;eax = content of Control Register 0
or al,1 ;set PM bit
mov cr0,eax ;switch to Protected Mode
jmp PMODE ;flush the processor's prefetch queue
PMODE:
sti ;enable interrupts
That should give you the idea.
Gunther
Quote from: Gunther on November 26, 2010, 02:10:15 PM
leetow2003,
as japheth pointed out: there is at least one simple error in your program. It's easy to switch into 32 bit Protected Mode:
cli ;disable interrupts
mov eax,cr0 ;eax = content of Control Register 0
or al,1 ;set PM bit
mov cr0,eax ;switch to Protected Mode
jmp PMODE ;flush the processor's prefetch queue
PMODE:
sti ;enable interrupts
That should give you the idea.
Gunther
One should NOT enable interrupts before having a valid IDT table (and handlers) setup... and you also need to reprogram the PIC (or APIC) controller...
Quote from: BogdanOntanu, November 26, 2010, at 02:13:52 PMOne should NOT enable interrupts before having a valid IDT table (and handlers) setup...
You're right. The above code was written from scratch and I've forgotten the following line:
cli ;disable interrupts
mov eax,cr0 ;eax = content of Control Register 0
or al,1 ;set PM bit
mov cr0,eax ;switch to Protected Mode
jmp PMODE ;flush the processor's prefetch queue
PMODE:
... ;other necessary operations in PM
sti ;enable interrupts
The crucial point is the jump.
Gunther
Quote from: Gunther on November 26, 2010, 02:10:15 PM
It's easy to switch into 32 bit Protected Mode:
jmp PMODE ;flush the processor's prefetch queue
PMODE:
It's easy, but it's not THAT easy. To switch from real-mode to 32-bit protected mode you need an inter-segment jump (from a USE16 to a USE32 segment). Your sample code won't do that.
The opposite direction, from 32-bit protected-mode to 16-bit real-mode, is a bit more complicated, because you'll have to switch to a 16-bit protected-mode code segment first, to set the proper attributes for CS, before switching to real-mode.
Quote from: japheth, November 26, 2010, at 06:55:59 PMTo switch from real-mode to 32-bit protected mode you need an inter-segment jump
Or an appropriate RETF without CALL. Both ways are possible. And yes, the above short code snippet enables only 16 bit PM.
Quote from: japheth, November 26, 2010, at 06:55:59 PMThe opposite direction, from 32-bit protected-mode to 16-bit real-mode, is a bit more complicated, ...
In any case, one will need valid selectors/descriptors for both: the 16 and the 32 bit segments. Assuming you have that, it's not so hard to switch back from 32 bit segment to the 16 bit segment, where you can finish the program via INT 21h.
Gunther
Thank all of you,although I haven't solved this problem,
I must thank all of you for helping me.I will continue
learning more knowledge,I hope you will continue helping
me.Thank you,thank you you very much.