ret does crash!?!

Programming, for all ages and all languages.
RedEagle
Member
Member
Posts: 31
Joined: Sat Nov 04, 2006 5:38 am
Location: Earth
Contact:

ret does crash!?!

Post by RedEagle »

Hi

first, the code:

Code: Select all

   jmp EnablePMode


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; GDT                                ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

GDT_START:

  gdt_NULL:
      dd 0
      dd 0

    
  gdt_CODE: 
     dw 0xFFFF 
     dw 0
     db 0
     db 10011010b ; 0x9A
     db 11001111b ; 0xCF
     db 0

  gdt_DATA: 
     dw 0xFFFF
     dw 0
     db 0
     db 10010010b ; 0x92
     db 11001111b ; 0xCF
     db 0

  gdt_VRAM: 
     dw 0x0F9F
     dw 0x8000
     db 0x0B
     db 10010010b ; 0x92
     db 00000000b ; 0x00
     db 0x00

GDT_END:

GDT_DESC:
   limit dw GDT_END - GDT_START - 1
   base  dd GDT_START+0x10000



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Selectoren                         ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

nullsel  equ 000000000000000b
codesel  equ 000000000001000b
datasel  equ 000000000010000b
vramsel  equ 000000000011000b

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PMode                              ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

EnablePMode:
   
   cli
   lgdt [GDT_DESC] ; GDT laden
  
    mov eax, cr0 ; Das CR0 Register in eax laden
    or  eax, 1   ; Das 0. Bit (PE Bit) auf 1 setzen
    mov cr0, eax ; Den neuen Wert in CR0 laden

    jmp long 0x08:PM2+0x10000

[Bits 32]
   PM2:
   
    ; Selector
    mov ax, datasel
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov ss, ax
    mov esp, 0x1FFFFF

     sti
     
     call check  ;;;;This is the Function
     chk01:
     jmp chk01


    jmp ende
   
;;;;TEST
check:
  push eax
  pop eax
ret    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CRASH
So:
I switch to PM. This works fine.
Than I want to call a function (check), works fine, too.
I push and pop something, works!
but at the ret, the PC reboots...

why?? I can jump, and I can use the Stack. Why does ret crash?

ps.: this foult happans on a real PC (I tested it with 2 PCs). With bochs, ret works.
mfg.: RedEagle
User avatar
XCHG
Member
Member
Posts: 416
Joined: Sat Nov 25, 2006 3:55 am
Location: Wisconsin
Contact:

Post by XCHG »

We can't be specific about the cause of the error unless we see where the RET crashes for you. Give us the code and we will be able to help you better.

In most of the cases I get a General Protection Fault in RETs that are returning to invalid addresses. The only cause for that is that I have not POPped as many values off of the stack as I have PUSHed them in when I created my stack frame. Again, I don't know if you are Assembly/C or any other programming language so try to be more specific.
On the field with sword and shield amidst the din of dying of men's wails. War is waged and the battle will rage until only the righteous prevails.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi,

I am interested about the fact you have set interrupts (STI). If this is the first time your have enetered PMode, you need a valid IDT and exception handlers before you enable interrupts.

I suspect that the CALL and RET are working fine, but you are getting something like a timer IRQ firing. Of course, the handler isn't present, so you get a triple fault as (I think) a null IDT tries to load zero (or garbage) in to the code segment.

HTH
Adam
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Post by JAAman »

AJ wrote:Hi,

I am interested about the fact you have set interrupts (STI). If this is the first time your have enetered PMode, you need a valid IDT and exception handlers before you enable interrupts.

I suspect that the CALL and RET are working fine, but you are getting something like a timer IRQ firing. Of course, the handler isn't present, so you get a triple fault as (I think) a null IDT tries to load zero (or garbage) in to the code segment.

HTH
Adam
ya, this is probably not the problem, but it is a problem

no, a unloaded IDT will be located at zero address (same as it was in RMode -- the intel manuals make no distinction between RMode IDTR and PMode IDTR), and will:
try to load values from the RMode IDT -- and those values are obviously wrong -- most likely segment > GDT.limit, which results in a GPF (iirc) which results in another segment > GDT.limit, which results in a double-fault, which results in another segment > GDT.limit, which results in a tripple-fault

so this is certainly a problem, you should leave interrupts disabled until you have an IDT and at least dummy handlers for all the hard-ints


mov ax, datasel
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov esp, 0x1FFFFF
i see you are placing 0x1FFFFF into esp -- this is not usually recommended, as it will result in frequent unaligned memory accesses -- and i doubt you have any other plans for address 1FFFFF...

you should set it to esp = 0X200000, which will result in the first value being placed at 0x1FFFFC-0x1FFFFF (but will not use 0x200000), what you are using now, the first value is at 0x1FFFFB-0x1FFFFE, and location 0x1FFFFF is never used

this isnt something that will cause the code not to work (usually), but it is something you should know, but probably didnt
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Post by mathematician »

Code: Select all

mov ax, datasel
should probably be:

Code: Select all

mov ax, cs:datasel
At the moment you are implicitly referencing datasel through the ds register, but the ds register is the very thing you are in the process of initialising. (Similarly the ss register, which is involved in all of the push, pop and ret instructions.)
Aali
Member
Member
Posts: 58
Joined: Sat Apr 14, 2007 12:13 pm

Post by Aali »

mathematician wrote:

Code: Select all

mov ax, datasel
should probably be:

Code: Select all

mov ax, cs:datasel
At the moment you are implicitly referencing datasel through the ds register, but the ds register is the very thing you are in the process of initialising. (Similarly the ss register, which is involved in all of the push, pop and ret instructions.)
an immediate value referenced through a segment? yeah.. that makes sense :wink:
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Post by mathematician »

Aali wrote:an immediate value referenced through a segment? yeah.. that makes sense :wink:
You think so too?
urxae
Member
Member
Posts: 149
Joined: Sun Jul 30, 2006 8:16 am
Location: The Netherlands

Post by urxae »

mathematician wrote:
Aali wrote:an immediate value referenced through a segment? yeah.. that makes sense :wink:
You think so too?
Hint: datasel is declared as

Code: Select all

datasel  equ 000000000010000b
That means it's not stored in some memory location, but encoded as an immediate value[1] directly in whatever instructions use it. The only segment involved is therefore cs, which is used to load the instruction including immediate value.


[1]: Or an address if enclosed in []s, but that doesn't make much sense in this case.
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Post by mathematician »

urxae wrote:
mathematician wrote:
Aali wrote:an immediate value referenced through a segment? yeah.. that makes sense :wink:
You think so too?
Hint: datasel is declared as

Code: Select all

datasel  equ 000000000010000b
That means it's not stored in some memory location, but encoded as an immediate value[1] directly in whatever instructions use it. The only segment involved is therefore cs, which is used to load the instruction including immediate value.


[1]: Or an address if enclosed in []s, but that doesn't make much sense in this case.
You shouldn't try irony on this site it would seem.
urxae
Member
Member
Posts: 149
Joined: Sun Jul 30, 2006 8:16 am
Location: The Netherlands

Post by urxae »

mathematician wrote:You shouldn't try irony on this site it would seem.
Sorry, didn't catch that.
My only excuses are that I didn't sleep well the night before and the fact that your post contained no smilies. Pick whichever you prefer :).
RedEagle
Member
Member
Posts: 31
Joined: Sat Nov 04, 2006 5:38 am
Location: Earth
Contact:

Post by RedEagle »

I'm sorry, that I can't test your tips...
but i have much Problems with winXP, so I not time to test it.

ps.:
sti was only a test, cause first I called a debugfunction, which uses the rs232, so i thought, that it was a couse, but later I recognized, that the ret-opcode couses it.

well
jmp and pop works perfectly, what does ret other do??
If winXP works, I'll test a far-jmp...
mfg.: RedEagle
User avatar
os64dev
Member
Member
Posts: 553
Joined: Sat Jan 27, 2007 3:21 pm
Location: Best, Netherlands

Post by os64dev »

did you enable the a20 address line because you have your stack pointer above 1MiB. Bochs always turns on a20, real computers generally don't.
Author of COBOS
RedEagle
Member
Member
Posts: 31
Joined: Sat Nov 04, 2006 5:38 am
Location: Earth
Contact:

Post by RedEagle »

Yes, A20 should be enabled.

After a long time, I continued searching the mistake.

First, my stack:

Code: Select all

    mov ax, datasel
    mov ss, ax
    mov esp, 0x200000
And this is the test-code:
push&pop after the pop, I have an other charecter

Code: Select all

    mov esi, 0xB8000
    mov al, '#'
      push ax
      pop ax
    mov [esi], al
    inc esi
    mov al, 0xAC
    mov [esi], al
read&write but here I get my '#' back

Code: Select all

    mov esi, 0xB8002
    mov al, '#'
      mov edi, 0x200000 
      mov [edi], al
      mov al, [edi]
    mov [esi], al
    inc esi
    mov al, 0xAC
    mov [esi], al
I can read and write to 0x200000 but not with push and pop. But why??
mfg.: RedEagle
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Not certain why the push and pop don't work if your stack is set up correctly, but the 2 pieces of code are not the same. I believe that your first frame of the stack will actually be 0x1FFFFC, not 0x200000 as esp will decrement before the push, IIRC.

Cheers,
Adam
RedEagle
Member
Member
Posts: 31
Joined: Sat Nov 04, 2006 5:38 am
Location: Earth
Contact:

Post by RedEagle »

Here, the '#' gets lost

Code: Select all

   mov esi, 0xB8002
    mov al, '#'
      mov edi, 0x1ffffc 
      mov [edi], al
      mov al, [edi]
    mov [esi], al
    inc esi
    mov al, 0xAC
    mov [esi], al
And here, I get it back.

Code: Select all

    mov esi, 0xB8004
    mov al, '#'
      mov edi, 0x200000 
      mov [edi], al
      mov al, [edi]
    mov [esi], al
    inc esi
    mov al, 0xAC
    mov [esi], al
Is the address below 0x200000 reserved??
mfg.: RedEagle
Post Reply