bootsect.s:我们如何在将代码本身移开后访问下一行?
bootsect.s: How com that we can access the next line after moving the code itself away?
本人是在线学习操作系统的新手,其中提到了bootsect.s:
https://kernel.googlesource.com/pub/scm/linux/kernel/git/nico/archive/+/v0.99-pl8/boot/bootsect.S
但是这段代码对我来说很陌生:
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
奇怪的是最后三行。按照我的理解,rep movsw
已经把代码本身移走了,所以当pc指向jumpi
,计算机要执行pc指向的代码时,应该会报错,因为代码jumpi go, INITSEG
已搬走。那么为什么这段代码仍然有效并且 jumpi go, INITSEG
仍然可以找到并执行?
来自
...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.
放心,代码还在!
当 BIOS 在线性地址 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:
一旦 rep movsw
指令完成其任务,00090000h 处的内存将包含在 00007C00h 处找到的 512 字节的精确 副本。虽然这段代码的作者说代码把自己移走了,但这只是口头上的问题。它始终是创建的副本。源字节仍然存在,除非 DS:SI
和 ES:DI
的 2 个内存区域之间存在重叠,但这里不是这种情况。
因此,指令指针将位于 00007C14h 并执行远跳转(段间)到线性地址 00090019h,其中 go 标签所在。
从这一点开始,可以忽略 00007C00h 的 512 个字节。
本人是在线学习操作系统的新手,其中提到了bootsect.s: https://kernel.googlesource.com/pub/scm/linux/kernel/git/nico/archive/+/v0.99-pl8/boot/bootsect.S 但是这段代码对我来说很陌生:
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
奇怪的是最后三行。按照我的理解,rep movsw
已经把代码本身移走了,所以当pc指向jumpi
,计算机要执行pc指向的代码时,应该会报错,因为代码jumpi go, INITSEG
已搬走。那么为什么这段代码仍然有效并且 jumpi go, INITSEG
仍然可以找到并执行?
来自
...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.
放心,代码还在!
当 BIOS 在线性地址 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:
一旦 rep movsw
指令完成其任务,00090000h 处的内存将包含在 00007C00h 处找到的 512 字节的精确 副本。虽然这段代码的作者说代码把自己移走了,但这只是口头上的问题。它始终是创建的副本。源字节仍然存在,除非 DS:SI
和 ES:DI
的 2 个内存区域之间存在重叠,但这里不是这种情况。
因此,指令指针将位于 00007C14h 并执行远跳转(段间)到线性地址 00090019h,其中 go 标签所在。
从这一点开始,可以忽略 00007C00h 的 512 个字节。