address in PMode
-
Tim
Re:address in PMode
You need to specify an origin, otherwise the assembler or linker won't know what values to write to the output file when you refer to a variable. If you don't want to bind your image to a certain address, you might want to look at the relocation records supported by formats such as COFF, PE and ELF.
- Pype.Clicker
- Member

- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:address in PMode
the idea behind relocations is the following: with your binary code, you receive a list of offsets where position-dependent places are. All you have to do to get a relocated image is
so for instance
will be assembled something like
your relocation list one single entry [080000b]
When relocating, you'll compute the difference between the requested address (0x0800.0000) and the effective load address (0x1234.5678) and add it to each entry
thus your program will look like
If you don't like relocating, you can use an ORG 0 and create a specific data & code segment for your program 
Code: Select all
for (r=reloc_entries;r<reloc_entries+nbrelocs;r++) {
*(dword*)(image+r.offset)+=base;
}
Code: Select all
org 0x8000000 ;; assume default loading @8MB
msg: db 'Hello World'
start:
mov esi, msg
mov al, PRINT_SYSCALL
int SYSCALL
mov al, EXIT_SYSCALL
int SYSCALL
Code: Select all
.data:
08000000: H e l l o W o r l d
.text
0800000b msi_imm 00 00 00 08
08000010 mal_imm 01
08000012 cc 80
08000014 mal_imm 02
08000016 cc 80
...
When relocating, you'll compute the difference between the requested address (0x0800.0000) and the effective load address (0x1234.5678) and add it to each entry
thus your program will look like
Code: Select all
0x12345678 : H e l l o W o r l d
0x12345683 : mi 78 56 34 12
0x12345688 : mi 01
0x1234568a : cc 80
...
-
drizzt
Re:address in PMode
Thanks a lot for your posts pype & tim... I will try one of these solutions a.s.a.p.
- Pype.Clicker
- Member

- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:address in PMode
by "creating specific" etc. i meant creating a code descriptor with base address = program load address and run it in this segment (a bit like DOS .com program worked) and do the same with the data segment.
-
drizzt
Re:address in PMode
OK, this was my first idea, but I had thought that it was not the best way to relocate code... Now I think that I will do so.
My aim is to execute code in extended memory... I wrote a real mode kernel but in real mode you can't do this, because CS segment is limited by a 16 bit offset (IP). So I would like to switch in protected mode, step by step, from my real mode kernel...
Maybe it's not the best way to realize a good kernel, but probably it's a good way to learn something about this difficult kind of programming...
So you must expect million questions from a PMode newbie... ;D
My aim is to execute code in extended memory... I wrote a real mode kernel but in real mode you can't do this, because CS segment is limited by a 16 bit offset (IP). So I would like to switch in protected mode, step by step, from my real mode kernel...
Maybe it's not the best way to realize a good kernel, but probably it's a good way to learn something about this difficult kind of programming...
So you must expect million questions from a PMode newbie... ;D
-
drizzt
Re:address in PMode
Ufff... this problem makes me dizzy... I try to update data & code selectors before jumping to the extended memory location but it continues to give me problems...
Well... first I load my image program at 0x200000 (2MB), then in my kernel I write:
And here is my GDT:
Why it doesn't work?! I mistake if modify GDT in this manner?
Well... first I load my image program at 0x200000 (2MB), then in my kernel I write:
Code: Select all
...
; Update code & data selectors
mov eax, 0x200000 ;<-- absolute address of the program image
mov [gdt_data+2], ax
mov [gdt_code+2], ax
shr eax, 16
mov [gdt_data+4], al
mov [gdt_code+4], al
mov [gdt_data+7], ah
mov [gdt_code+7], ah
; Jump to the memory location 0x200000
jmp CODE_SEL:0
Code: Select all
gdt: dw 0 ; limit 15:0
dw 0 ; base 15:0
db 0 ; base 23:16
db 0 ; access byte (descriptor type)
db 0 ; limit 19:16, flags
db 0 ; base 31:24
DATA_SEL equ $-gdt
gdt_data:
dw 0xFFFF ; Limit/Length
dw 0 ; Base 0
db 0 ; Base 0
db 0x92 ; present, ring 0, data, expand-up, writable
db 0xCF ; page-granular, 32-bit
db 0 ; Base 0
CODE_SEL equ $-gdt
gdt_code:
dw 0xFFFF ; Limit/Length
dw 0 ; Base 0
db 0 ; Base 0
db 10011110b ; P=1, DPL=0, DT=0, ?, Code: conforming, exec/read (1,0,0,1,1110)
db 0xCF ; G=1, D=1, 0, AVL=0, 1111=F: Limit/Length (1,1,0,0,1111)
db 0 ; Base 0
REAL_CODE_SEL equ $-gdt
dw 0xFFFF ; Limit/Length
dw 0 ; Base 0
db 0 ; Base 0
db 0x9A ; P=1, DPL=0, DT=0, ?, Code: conforming, exec/read (1,0,0,1,1110)
db 0
db 0 ; Base 0
gdt_end:
- Pype.Clicker
- Member

- Posts: 5964
- Joined: Wed Oct 18, 2006 2:31 am
- Location: In a galaxy, far, far away
- Contact:
Re:address in PMode
ouch ouch ouch !
You need to know that changes made to the GDT are commited to cpu only when the segment registers are re-loaded (they hold a cached version of the actual base & limit ...)
so you'll at least need a
Moreover, i suggest you use separate selectors for kernel & program codes...
You need to know that changes made to the GDT are commited to cpu only when the segment registers are re-loaded (they hold a cached version of the actual base & limit ...)
so you'll at least need a
Code: Select all
mov ds,PROG_DATA_SEL
jmp PROG_CODE_SEL:0
-
drizzt
Re:address in PMode
ok... it was a stupid problem ::), but there's another error; if I don't use a jmp far when I jump to the program in extended memory it doesn't work. It seems to me strange... I thought that a simple jmp was ok to update code selector... and then it do a triple fault when my application (in ext mem) do an int instruction... maybe there's a problem also in the IDT... well I will have to study my IDT better. Thanks a lot for now...
-
Curufir
Re:address in PMode
HelpPC:drizzt wrote: ...if I don't use a jmp far when I jump to the program in extended memory it doesn't work. It seems to me strange... I thought that a simple jmp was ok to update code selector...
JMP - Unconditional Jump
Usage: JMP target
Modifies flags: None
Unconditionally transfers control to "label". Jumps by default are within -32768 to 32767 bytes from the instruction following the jump. NEAR and SHORT jumps cause the IP to be updated while FAR jumps cause CS and IP to be updated.
Unless you explicitly do a far jump the code segment isn't changed. I think you can do the same thing with a RETF after pushing selector (Certainly can with segments in real mode) and ip onto the stack, but I haven't tried it yet.
Curufir
-
drizzt
Re:address in PMode
Yes, but if I write jmp CODE_SEL:0 I think that it's automatically assembled with a far jump.
P.S. I forgot to say that I'm using NASM 0.98 for windows.
P.S. I forgot to say that I'm using NASM 0.98 for windows.