linux环境下修改linux0.11 bootsect.s并用qemu运行的问题

看了bootsect.s,我想在linux下直接编译,并用qemu 模拟器运行,但是有问题,我将代码最简化,发现可能是段间跳转和ds,es寄存器设置的问题,请帮忙看下是哪里不对,谢谢了,问题描述如下:
bootsect.s的代码:
.set BOOTSEG, 0x07c0
.set INITSEG, 0x9000

.globl start
start:
.code16

# print some inane message
  movw $0x0300,%ax #read cursor position
  xorb %bh,%bh
  int $0x10

  movw $28,%cx
  movw $0x0004,%bx
  movw $msg,%bp
  movw $0x1301,%ax # write string and move cursor
  int $0x10

# mov this sector to 0x9000 and then jmp to next instruction
  movw $BOOTSEG, %ax
  movw %ax, %ds # source addr ds:si
  movw $INITSEG, %ax
  movw %ax, %es # dest addr es:di
  xorw %si, %si
  xorw %di, %di
  movw $256, %cx # 256 *2 = 512 bytes
  rep
  movsw
  ljmp $INITSEG, $go

go:
  movw $0x0300,%ax #read cursor position
  xorb %bh,%bh
  int $0x10

  movw $28,%cx
  movw $0x0004,%bx
  movw $msg,%bp
  movw $0x1301,%ax # write string and move cursor
  int $0x10



loop:
  jmp loop

msg:
  .byte 13, 10 #CR LF carriage returns line feeds
  .ascii "Loading system ... ^_^"
  .byte 13, 10, 13, 10

.org 510
  .word 0xaa55

用了shell脚本来编译make.sh:
as bootsect.s -o bootsect
ld -m elf_i386 -N -e start -Ttext 0x7c00 bootsect -o bootblock
objcopy -S -O binary bootblock
qemu -hda bootblock
问题:我是想显示 Loading system ... 然后将这个启动扇区移动到0x9000处跳到标号go并重新显示Loading system ...以验证移动成功,但是,只能显示第一次的Loading system ...,如果没有中间的那段移动启动扇区的代码,那么能够显示两次Loading system ...,请大家看下是哪里的问题,谢谢:)

作者: dalinthegreat   发布时间: 2011-05-08

1. ljmp $INITSEG, $go 执行的时候是jmp far 9000:7c30,问题就来了,只是复制到了0x9000:0处,而9000:7c30处全是0,跳转过去肯定不对了,应该是ljmp $INITSEG, $0x30才对,这里的0x30就是0x7c30-0x7c00得出来的
2. 在做扇区移动的时候es的值被改为了9000,当调用执行int 0x10的时候,es:bp指向的地方是没有数据的,仍然全是0
3. bios 0x10号中断的0x13号功能应该要设置"DH,DL=起始行,列",你的代码里好像没有呢。
PS: 你可以用bochs去debug这个bootsector,问题出在哪里很容易发现的
修改后的代码:
Assembly code

.set BOOTSEG, 0x07c0
.set INITSEG, 0x9000

.globl start
start:
.code16

# print some inane message
  movw $0x0300,%ax #read cursor position
  xorb %bh,%bh
  int $0x10

  movw $28,%cx
  [color=#FF0000]movw $0x0, %dx[/color]
  movw $0x0004,%bx
  movw $msg,%bp
  movw $0x1301,%ax # write string and move cursor
  int $0x10

# mov this sector to 0x9000 and then jmp to next instruction
  movw $BOOTSEG, %ax
  movw %ax, %ds # source addr ds:si
  movw $INITSEG, %ax
  movw %ax, %es # dest addr es:di
  xorw %si, %si
  xorw %di, %di
  movw $256, %cx # 256 *2 = 512 bytes
  rep
  movsw
  [color=#FF0000]ljmp $INITSEG, $0x30[/color]

go:
  [color=#FF0000]movw $0, %ax
  movw %ax, %es[/color]
  movw $0x0300,%ax #read cursor position
  xorb %bh,%bh
  int $0x10
  
  movw $28,%cx
  movw $0x0004,%bx
  [color=#FF0000]movw $0x0100, %dx[/color]
  movw $msg,%bp
  movw $0x1301,%ax # write string and move cursor
  int $0x10



loop:
  jmp loop

msg:
  .byte 13, 10 #CR LF carriage returns line feeds
  .ascii "Loading system ... ^_^"
  .byte 13, 10, 13, 10

.org 510
  .word 0xaa55


作者: zhang19871112   发布时间: 2011-05-09

我晕,红色字体显示代码居然不好用,重贴一次:
Assembly code

.set BOOTSEG, 0x07c0
.set INITSEG, 0x9000

.globl start
start:
.code16

# print some inane message
  movw $0x0300,%ax #read cursor position
  xorb %bh,%bh
  int $0x10

  movw $28,%cx
  movw $0x0, %dx
  movw $0x0004,%bx
  movw $msg,%bp
  movw $0x1301,%ax # write string and move cursor
  int $0x10

# mov this sector to 0x9000 and then jmp to next instruction
  movw $BOOTSEG, %ax
  movw %ax, %ds # source addr ds:si
  movw $INITSEG, %ax
  movw %ax, %es # dest addr es:di
  xorw %si, %si
  xorw %di, %di
  movw $256, %cx # 256 *2 = 512 bytes
  rep
  movsw
  ljmp $INITSEG, $0x30

go:
  movw $0, %ax
  movw %ax, %es
  movw $0x0300,%ax #read cursor position
  xorb %bh,%bh
  int $0x10

  movw $28,%cx
  movw $0x0004,%bx
  movw $0x0100, %dx
  movw $msg,%bp
  movw $0x1301,%ax # write string and move cursor
  int $0x10



loop:
  jmp loop

msg:
  .byte 13, 10 #CR LF carriage returns line feeds
  .ascii "Loading system ... ^_^"
  .byte 13, 10, 13, 10

.org 510
  .word 0xaa55


作者: zhang19871112   发布时间: 2011-05-09