JMPing к 0x7C00 в загрузчике не вызывает бесконечный цикл - PullRequest
0 голосов
/ 05 ноября 2019

Я создаю загрузчик и хотел создать бесконечный цикл из интереса, перепрыгивая по адресу 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

Я также попытался создать метку start в строке 3 и либо CALL start, либоJMP start в строке 17. Похоже, ничего из этого не работает.

1 Ответ

4 голосов
/ 05 ноября 2019

Вы не call printMsg, поэтому RET на return: некуда деваться. Кроме того, ваш jmp 0x7c00 находится не в том месте, он недоступен.

Более того, как сказал Питер , вы не гарантированно получите 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
...