【问题标题】:JMPing to 0x7C00 in bootloader does not cause infinite loop在引导加载程序中跳转到 0x7C00 不会导致无限循环
【发布时间】:2019-11-05 11:32:05
【问题描述】:

我正在创建一个引导加载程序,并想通过跳转到地址 0x7C00 来创建一个无限循环。

由于引导加载程序加载到 0000:7C00,我希望当我调用 JMP 0x7C00 时,代码会转到程序的开头。除了它调用代码一次,就是这样。

这是我的代码:

  1 BITS 16
  2 ORG 0x7C00
  3 
  4 MOV AX, 0
  5 MOV DS, AX
  6 MOV SI, 0x7C00
  7 
  8 LEA BX, [msg]
  9 
 10 printMsg:
 11   MOV AL, [BX]
 12   INC BX
 13   CMP AL, 0
 14   JZ return
 15   CALL printc
 16   JMP printMsg
 17 JMP 0x7C00
 18   
 19 printc:
 20   MOV AH, 0Eh
 21   int 10h
 22   RET
 23 
 24 return:
 25   RET
 26 
 27 
 28 msg: db "Hello",0
 29 
 30 times 510-($-$$) db 0x90
 31 dw 0xAA55

我还尝试在第 3 行创建 start 标签,并在第 17 行创建 CALL startJMP start。但这似乎都不起作用。

【问题讨论】:

  • 你的jmp在哪里?我看到的唯一一个是JMP printMsg。你也没有call printMsg 所以RETreturn: 将无处可去。
  • 由于引导加载程序被加载到 0000:7C00,你不能依赖它。一些“损坏”的 BIOS 显然会使用 CS:IP=07C0:0000 跳入 MBR。但是,是的,使用该 ORG 指令,NASM 会将jmp 0x7c00 组装成一个相对跳转,就像您在文件顶部放置一个标签一样。但实际上,您首先应该这样做; x86 没有绝对直接近跳转,只有相对、绝对间接和远跳转(设置新的 CS 和 IP)。无论如何,使用 BOCHS 调试器来单步执行您的代码,如果这不起作用,请发布 minimal reproducible example 会发生什么。
  • 对不起@Jester 我发布了错误的代码。我已经更新了。
  • 您的JMP 0x7C00 紧跟在另一个jmp 之后,因此永远无法到达。
  • 使用调试器单步执行您的代码。

标签: assembly x86 nasm x86-16


【解决方案1】:

您没有call printMsg,所以return: 上的RET 将无处可去。另外你的jmp 0x7c00 放错地方了,无法访问。

此外,作为Peter said,您不能保证拥有CS:IP = 0000:7C00,它可能是07C0:0000,具体取决于BIOS 实现。尽管如此,使用ORG 0x7C00 指令,NASM 将把jmp 0x7c00 组装成一个相对跳转,就好像您在文件顶部放置了一个标签一样。但实际上,您首先应该这样做。

因此,固定版本可能如下所示:

BITS 16
ORG 0x7C00

start:

XOR AX, AX
MOV DS, AX

; you could also put the start label here
; no need to reload DS
LEA BX, [msg]
CALL printMsg
JMP start

printMsg:
  MOV AL, [BX]
  INC BX
  TEST AL, AL
  JZ return
  CALL printc
  JMP printMsg
return:
  RET

printc:
  MOV AH, 0Eh
  int 10h
  RET

msg: db "Hello",0

times 510-($-$$) db 0x90
dw 0xAA55

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-16
    • 2015-12-18
    • 2016-06-05
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 2013-06-13
    相关资源
    最近更新 更多