How do I reallocate some code during execution? I'm writing a boot sector that will use chain loading. So the first thing I do in my boot sector is to load itself to another location (I do this by reading it from disk again, but I assume there is a good way of moving 512 bytes without having to re-read them?). Now I would like to continue the execution of my code, but on the new location. So I have something like
[BITS 16]
[ORG 0x7C00]
; Load this code to for instance 0x6000.. this I know how to do
; Here I want to jump to the corresponding place in the code when the code is loaded to 0x6000
bootsector_continue:
; Do something else
How do I do this? Because my boot sectors assumes that it starts on 0x7C00, but it will no longer be there after the relocation (and I can't have another [ORD 0x6000] right?)
Realocate code during execution (chain loading)
- gzaloprgm
- Member
- Posts: 141
- Joined: Sun Sep 23, 2007 4:53 pm
- Location: Buenos Aires, Argentina
- Contact:
Re: Realocate code during execution (chain loading)
You can use rep movsb to copy some amount of bytes into one location to another:How do I reallocate some code during execution? I'm writing a boot sector that will use chain loading. So the first thing I do in my boot sector is to load itself to another location (I do this by reading it from disk again, but I assume there is a good way of moving 512 bytes without having to re-read them?). Now I would like to continue the execution of my code, but on the new location. So I have something like
Rep movsd ;Copies CX bytes from DS:SI to ES:DI
I think you should use ORG 0 and use segments (so bootsector_continue is in 0x600:bootsector_continue)[BITS 16]
[ORG 0x7C00]
; Load this code to for instance 0x6000.. this I know how to do
; Here I want to jump to the corresponding place in the code when the code is loaded to 0x6000
bootsector_continue:
; Do something else
How do I do this? Because my boot sectors assumes that it starts on 0x7C00, but it will no longer be there after the relocation (and I can't have another [ORD 0x6000] right?)
Cheers,
Gonzalo
Visit https://gzalo.com : my web site with electronic circuits, articles, schematics, pcb, calculators, and other things related to electronics.
Re: Realocate code during execution (chain loading)
Thanks!
But can I put [ORG 0] just anywhere in my code? Or how do you mean? I know about protected mode and segments but I haven't used it enough to know exactly what you mean..
But can I put [ORG 0] just anywhere in my code? Or how do you mean? I know about protected mode and segments but I haven't used it enough to know exactly what you mean..
-
- Member
- Posts: 524
- Joined: Sun Nov 09, 2008 2:55 am
- Location: Pennsylvania, USA
Re: Realocate code during execution (chain loading)
Put it in the beginning, then use something like
These are real mode segments, not pmode segments. Protected mode segments are offsets into a GDT, and this code doesn't enter protected mode or load a GDT. You can still do that later though
Code: Select all
[ORG 0]
jmp 07C0h:entry ; Set CS to a known value
entry:
mov ax, cs
mov ds, ax ; Make DS the same as the code segment
mov ax, 0600h
mov es, ax ; Make ES the destination segment
xor di,di
xor si,si
mov cx, 512 ; Moving 512 bytes of code
cld
rep movsb
jmp 0600h:postmove ; jump into newly written code
postmove:
mov ax, cs ; Set all segments to code segment
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
Re: Realocate code during execution (chain loading)
Thanks a lot! But usually when you write [ORG 0x7C00], which instructions are there that needs to know where in memory the program is? Isn't most jump-instructions near jumps and so on.
Secondly, you chose to move the code to 0600h and not 06000h, why is that? When you do "jmp 0x600h:postmove", you jump to address 0x6000h + postmove, right? So shouldnt it be loaded into 0x6000h?
Secondly, you chose to move the code to 0600h and not 06000h, why is that? When you do "jmp 0x600h:postmove", you jump to address 0x6000h + postmove, right? So shouldnt it be loaded into 0x6000h?
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: Realocate code during execution (chain loading)
No, addressing is different in Real Mode
Re: Realocate code during execution (chain loading)
Yes, you can put an org statement anywhere. You can either set the code and data segments as suggested, or just use [org 0x6000] and not worry about changing cs,ds,es,fs,gs (as long as it won't overflow the 64k page boundary). It is limited to 0x6000 -> 0xffff, so you will have 0x10000-0x6000 = 0xA000, or 40,960 bytes to play with if you don't use segmentation, if you do use segmentation, you will have an entire 64k to play with. (Either should suffice for a first stage boot loader!) My master boot record replacement does this, it copies itself out of the way, then copies in the first sector of the partition you chose to the location 0x7c00 (hence having to move itself out of the way).
Please read up a bit on segmentation, it will explain why it appears he's loading it at 0x600 rather than 0x6000, since he is setting ax = 0x600, and es = ax... this sets the segment register to 0x600. In real mode, it uses this segment base (0x600) and di (es:di pair), so that means it will actually load to 0x6000 (es << 4) + di.
Ok, I was going to comment on the code, but here is the code how I would do it .
Please read up a bit on segmentation, it will explain why it appears he's loading it at 0x600 rather than 0x6000, since he is setting ax = 0x600, and es = ax... this sets the segment register to 0x600. In real mode, it uses this segment base (0x600) and di (es:di pair), so that means it will actually load to 0x6000 (es << 4) + di.
Ok, I was going to comment on the code, but here is the code how I would do it .
Code: Select all
[bits 16]
[org 0x7c00]
jmp 0x00:entry ;Set CS to a known value (0)
entry:
;Clear all segment registers so we need not touch them again!
xor ax, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
;From here on I don't play with segments anymore, keeps things simple, especially for people reading my code who aren't completely familiar with segmentation, and makes it easier to port to other platforms that don't support segmentation
cld
mov si, 0x7c00
mov di, 0x6000
mov cx, 512/4 ;Why do this one byte at a time, lets do a double word at a time
rep movsd ;This does the copy
jmp new_entry ; Jump to our new location :)
[org 0x6000] ;Reset our origin
new_entry:
;Finish what you wanted to out of the way now
-
- Member
- Posts: 524
- Joined: Sun Nov 09, 2008 2:55 am
- Location: Pennsylvania, USA
Re: Realocate code during execution (chain loading)
Not always. NASM doesn't let you put a second ORG statement. Segments are probably a better way to do it, because you can relocate the code anywhere at runtime, and its not limited to the first 64kb.Ready4Dis wrote:Yes, you can put an org statement anywhere.