在引导加载程序中跳转到0x7C00不会引起无限循环

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在引导加载程序中跳转到0x7C00不会引起无限循环相关的知识,希望对你有一定的参考价值。

我正在创建一个引导程序,并希望通过跳转到地址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。不过,这似乎都无效。

答案

您没有call printMsg,因此RET处的return:将无处可去。另外,您的jmp 0x7c00放在错误的位置,无法访问。

此外,由于Peter said,不能保证您拥有CS:IP = 0000:7C00,根据Bios的实现,它可能是07C0:0000。尽管如此,使用该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

以上是关于在引导加载程序中跳转到0x7C00不会引起无限循环的主要内容,如果未能解决你的问题,请参考以下文章

STM32L073RZ (rev Z) IAP 跳转到引导加载程序(系统内存)

CPU工作原理

主引导记录的内存地址为什么是0x7C00

Linux0.11内核系列—1.引导程序分析

Linux源码学习---引导程序boot

Cortex M4 的引导加载程序 - 跳转到加载的应用程序