2

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?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Changda Li
  • 123
  • 1
  • 8
  • 2
    Movs copies memory; it doesn’t change the source buffer. – prl Jun 11 '19 at 06:03
  • Thanks for your answer! But the code is first moved to memory and then being fetched from memory one line at a time and executed, is it correct? Or is there an additional procedure in between, like a block of code is fetched from memory to the source buffer, and then the cpu fetches from source buffer line by line and executes them? – Changda Li Jun 11 '19 at 06:13
  • 1
    `rep movsw` _copies from_ `ds:si` to `es:di`. Does that clear up your confusion? You appear to think that either a) the move changes the source buffer as prl mentioned, or b) that the move operation is the other way (`es:di` -> `ds:si`). – Simon Whitehead Jun 11 '19 at 06:35
  • I tagged this `as86`; I think that's what early Linux used. – Peter Cordes Jun 11 '19 at 09:36
  • 1
    Offtopic note: If the BIOS left the stack (`ss:sp`) pointing to the area used for `#INITSEG`, then an IRQ can occur after the boot sector is copied (but before the boot loader sets up the stack properly at lines 83 and 84) causing the copy to be corrupted (by the IRQ handler's stack) before/while it's being executed. In other words, to avoid (a small chance of) "bad things" the stack should be setup before the boot sector is copied to `#INITSEG`. – Brendan Jun 11 '19 at 10:43
  • 1
    Hi @SimonWhitehead, thanks for you clarification. I think I got b) correctly. But what I'm most confused is that, based on my understanding, the code shown above will be moved from #BOOTSEG to #INITSEG(and line 13-14 in the initial file also proves this), 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. Is it still executed because of the source buffer? Is source buffer an additional layer between memory and CPU? – Changda Li Jun 11 '19 at 16:25

1 Answers1

3

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:SIand 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.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76