I'm a newbee learning operating system online, in which bootsect.s is mentioned: https://kernel.googlesource.com/pub/scm/linux/kernel/git/nico/archive/+/v0.99-pl8/boot/bootsect.S But this piece of code is quite strange to me:
mov ax,#BOOTSEG
mov ds,ax
mov ax,#INITSEG
mov es,ax
mov cx,#256
sub si,si
sub di,di
cld
rep
movsw
jmpi go,INITSEG
The strange part is the last 3 lines. According to my understanding, rep movsw
has already move the code itself away, so when pc points to jumpi
and when the computer is about to execute the code pointed by pc, it should cause an error because the code jumpi go, INITSEG
has been moved away. So how come this code still works and jumpi go, INITSEG
can still be found and executed?
From the OP's comment
...but the pc is pointed to the section start with #BOOTSEG, where there is no code anymore. So I thought jumpi go,INITSEG will not execute.
Rest assured, the code is still there!
This is how the memory was filled when BIOS loaded the bootsector at linear address 00007C00h:
00007C00 mov ax,#BOOTSEG ; 07C0h
00007C03 mov ds,ax
00007C05 mov ax,#INITSEG ; 9000h
00007C08 mov es,ax
00007C0A mov cx,#256
00007C0D sub si,si
00007C0F sub di,di
00007C11 cld
00007C12 rep movsw
00007C14 jmpi go,INITSEG ; Far jump (EAh, 19h, 00h, 00h, 90h)
00007C19 go:
Once the rep movsw
instruction has done its business, the memory at 00090000h will contain an exact copy of the 512 bytes found at 00007C00h. Although the author of this code stated that the code moves itself away, this is only a matter of speech. It is always a duplicate that is created. The source bytes are still there, unless of course there was an overlap between the 2 memory regions at DS:SI
and ES:DI
but that is not the case here.
As a consequence the instruction pointer will be at 00007C14h and execute the far jump (intersegment) to linear address 00090019h where the go label is.
From this point on the 512 bytes at 00007C00h can be ignored.