News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

An unknown error in FAR JUMP, CALL

Started by woonsan, March 23, 2008, 06:24:50 AM

Previous topic - Next topic

woonsan

I made a program that runs in Protected-Mode.
When I executed normal code, it doesn't occur any errors but, if i try to execute FAR JUMP or FAR CALL, it's gonna be rebooted.
I don't know why it does like this.

(I've written the code that uses FAR JUMP&CALL successfully, but in this time, it occurs an unknown error ..)

My routine to enable Protected-Mode and after is like below,
I. Jumped by Boot Loader (Running in Real-Mode)
II. Initialize all segments
III. Disable interrupts with cli and PIC control.
IV. Relocate GDT
V. Load GDT
VI. Enter into Protected-Mode
VII. Far Jump to entrance point of 32-bit code in 32-bit Code Selector
VIII. Initialize all segments of 32-bit
IX. Enable A20

Summary of the Error
In the routine what I described above, it works. But, after this, If I try to execute FAR something, it makes error...
In Protected-Mode, I tried to execute the code below.
  a1:
   nop
  jmp far [cs:a1]
If I try to execute this code, it's gonna be rebooted. Actually, it doesn't have any errors.

So, I tried to trace the error from another section that like GDT, Initialization Section.
When I wrote this code, I refered a code what I wrote before that works. And, I compared this code with the code but I can't find any problems.

> Code Segment Descriptor in GDT
dw 0xFFFF
dw 0x0000
db 0x02
db 0x9A
db 0xCF
db 0x00
Summary of Descriptor : Limit=0xFFFFF, Base Address=0x20000, P=1, DPL=0, Code, Non-Conforming, Readable, G=1, D=1


Maybe, I think that someone who experienced for many times knows about this problem so I ask.

Please let me know, Thanks.

Tedd

"VII. Far Jump to entrance point of 32-bit code in 32-bit Code Selector"

"jmp far [cs:a1]"


You can't use the 'old' value of cs as it's still a 16-bit descriptor - you need to use a 32-bit code descriptor from your new gdt.
You better read up segment selectors first, but if your first entry (after the NULL descriptor) was the correct selector then you'd do "jmp far [08h:a1h]"
No snowflake in an avalanche feels responsible.

woonsan

Tedd/ Thanks for your reply. But, I already wrote the code that to change selector's value as 32-bit Protected-Mode's successfully. (So, the other code works)
When I tried to write some data on Video Memory with its own Selector(what points to 0xB8000) and Data Selector that has Base Address as 0x0, it works.
I got this problem when I was writing a routine to enable interrupt. I called an interrupt. But, it was rebooted. So I tried to jump to the address of interrupt with FAR CALL directly but, its result was as same as INTERRUPT CALL's that just reboot.
I can't guess any reason that it reboots.

Tedd

If you still mean the same error...
Quote
In the routine what I described above, it works. But, after this, If I try to execute FAR something, it makes error...
In Protected-Mode, I tried to execute the code below.
  a1:
   nop
  jmp far [cs:a1]
If I try to execute this code, it's gonna be rebooted. Actually, it doesn't have any errors.
Actually, it does have errors. The error is that you're using CS.
CS continues to hold the value for its 16-bit segment until you do the far jump. The far jump will reload the value of CS, which is why it must be a far jump, and why is must be a valid 32-bit code descriptor.
Change it to "jmp far [08:a1]" -- or whichever value makes sense (jumping to CS: is wrong!)


If you did fix that one and this is a different error, check your IDT is correct and aligned, and that its entries are correct and point to valid code entry points.
No snowflake in an avalanche feels responsible.

woonsan

Tedd/ Hmm.. I think that I have to write the code to change CPU to Protected-Mode.

<---------------------------------------------------------- Source Code ---------------------------------------------------------->
; start - Entry Point
[bits 16]
start:
; Initialize segments
mov ax, cs
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ax, _SEGMENT_INIT_REAL_STACK
mov ss, ax
mov sp, _POINT_INIT_REAL_STACK

; Draw screen
lea si, [screen_shape]
call screen_printstring

; Disable All Interrupts [With PICs']
cli                              ; Disable all interrupts in CPUs
mov al, 0x11                           ; Initialization
out 0x20, al                           ; To Master
out 0xA0, al                           ; To Slave

mov al, 0x20                           ; Start of Master IRQs
out 0x21, al                           ; To Master
mov al, 0x28                           ; Start of Slave IRQs
out 0xA1, al                           ; To Slave

mov al, 0x4                           ; Slave is connected to IRQ2 of Master
out 0x21, al                           ; To Master
mov al, 0x2                           ; IRQ1 of Slave is connected to Master
out 0xA1, al                           ; To Slave

mov al, 0x1                           ; Use 8086 Mode
out 0x21, al                           ; To Master
out 0xA1, al                           ; To Slave

mov al, 0xFB                           ; Disable all interrupts of Master except IRQ2
out 0x21, al                           ; To Master
mov al, 0xFF                           ; Disable all interrupts of Slave
out 0xA1, al                           ; To Slave

; Relocate GDT
mov ax, (_ADDRESS_GDT / 0x10)                     ; Address of GDT Segment to be copied
mov es, ax                           ; Set Extra-Segment
mov cx, (gdt_size + 1)                        ; Size to copy
lea si, [gdt_register]                        ; Address of Source GDT
xor di, di                           ; Destination Offset 0
cld                              ; Clear direction-flag
rep movsb                           ; Copy for CX-times

; Get into Protected-Mode
lgdt [es:0x0]                           ; Load GDT Register
mov eax, cr0                           ; Load CR0 into EAX
or eax, 0x1                           ; Enable PE bit
mov cr0, eax                           ; Apply changes on CR0

jmp dword _SELECTOR_INITIALIZER_CODE:entry_32               ; Jump to Protected-Mode Entry Point

; entry_32 - 32-bit Protected Mode Entry Point
[bits 32]
entry_32:
; Initialize segments
mov ax, _SELECTOR_INITIALIZER_DATA
mov ds, ax
mov ss, ax
mov esp, _POINT_INIT_PROTECTED_STACK
mov es, ax
mov fs, ax
mov gs, ax

; Enable A20
call a20_enable

; Get Total Memory Size
mov edi, 0x100000                        ; After the last address of Present-Memory-Map
xor eax, eax                           ; Initialize Checksum
gettotalmem:                           ; Loop section to get total memory size
  mov dword [edi], eax                        ; Try to write
  cmp dword [edi], eax                        ; If not existing memory
  jne gettotalmem_final                        ; Jump to final section
  add edi, 0x100000                        ; Next 1MB
  inc eax                           ; Increase checksum
jmp gettotalmem                        ; Loop
gettotalmem_final:                        ; Final Section
mov dword [pv_MemorySize], edi                     ; Memory Size

;; Calculate total memory size to MB
;mov eax, dword [pv_MemorySize]
;mov ebx, 0x100000
;div ebx

;; Print total memory
;mov cl, 10
;lea edi, [publicbuffer_1]
;lea ebx, [string_table_itoa]
;call string_itoa

;lea esi, [publicbuffer_1]
;lea edi, [publicbuffer_2]
;call string_reverse

;lea esi, [publicbuffer_1]
;call screen_printstring32

; Build IDT
mov edx, 0x100                           ; Count to fill as Not Used Descriptor
lea esi, [idt_notused]                        ; Address of Not Used Descriptor
lea edi, [_ADDRESS_IDT]                     ; Address of IDT
mov ecx, 8                           ; Size of a Descriptor
buildidt_fillnotused:                        ; Loop to fill
  call memory_copy                        ; Copy the descriptor
  add edi, 8                           ; Next descriptor
  or edx, edx                           ; If descriptor filling count is zero
  jz buildidt_fillnotused_final                     ; Exit from the loop
  dec edx                           ; Decrease count
jmp buildidt_fillnotused                     ; Loop
buildidt_fillnotused_final:                     ; Exit point of the loop

lidt [ds:idt_register]                        ; Load IDT Register

a1:
nop
nop
nop
jmp far [a1]
;call far [cs:isr_notused]

jmp $
<----------------------------------------------------------------------------------------------------------------------------------------->


Actually, I think that when I jumped as far with CS, CS contains selector of 32-bit. Because on the code, I wrote that "jmp dword _SELECTOR_INITIALIZER_CODE:entry_32"
And I initialized all the segment registers as correct value. So, I think the error is not by wrong value of CS because that was initialized.
In addition, at the first time, I tried to change the value of CS directly (But If I tried this, this also occurs an error/ mov ax, _SELECTOR_INITIALIZER_CODE / mov cs, ax)

MichaelW

eschew obfuscation


Tedd

Okay, that looks mostly fine.. although the data section may have been helpful.

So, the question is what is stored at "a1h"? And what are you expecting it to be? Plus it's an uneven/unaligned address.
More importantly, what are you trying to achieve by making a far jump to its contents? Would it even make sense, now that you're in protected mode?
If you're just trying to test your interrupt handlers, it's best to force the interrupt directly (either through causing an exception, or the int instruction.)
No snowflake in an avalanche feels responsible.

woonsan

Quote from: Tedd on March 28, 2008, 07:43:07 PM
Okay, that looks mostly fine.. although the data section may have been helpful.

So, the question is what is stored at "a1h"? And what are you expecting it to be? Plus it's an uneven/unaligned address.
More importantly, what are you trying to achieve by making a far jump to its contents? Would it even make sense, now that you're in protected mode?
If you're just trying to test your interrupt handlers, it's best to force the interrupt directly (either through causing an exception, or the int instruction.)


I would like to make an application that runs without Operating System. (Actually, it seems an operating system.)
Previously, I have written a code like this. So, I referred the code to write this code. (the previous code works/Protected-Mode+Paging)
/
I have tested the address of label 'a1'. (By seeing opcode)
But, It was pointing a correct address to execute.