Почему BX разрушается после ЗВОНКА? - PullRequest
1 голос
/ 27 марта 2020

Я пишу asm (x86_64) для загрузчика (16-битный реальный режим), и похоже, что мои регистры разрушаются после CALL.

Мой первый файл выглядит примерно так.

mov bx, 0x1234 ;moves 16 bits into the register BX (bl is ascii for "4")
call hexprint  ;call function

Функция hexprint выглядит следующим образом:

hexprint:
    mov ah, 0x0e  ;set bios to teletype mode
    mov al, bl    ;move the value from bl to al, (0x34)
    int 0x10      ;make bios print
    ret

однако, когда я загружаю ее в QEMU, она не печатает 4.

Некоторые тесты, которые я запускаю, :

  • делает mov bx, 0x1234 в printhex. Это работает и печатает 4
  • , как в фрагменте кода, я удалил инструкцию pusha с самого начала функции. Я предположил, что push es и pusha могут удалить или, по крайней мере, не быть определены для сохранения значения в регистре после загрузки в стек, но, похоже, это не является источником проблемы.
  • Я еще не пробовал писать свои собственные версии call и ret

В настоящее время я предполагаю, что в моей реализации вызова регистры искажаются, но я не знаете, как мне это исправить.

MRE:

boot_sect.asm

[org 0x7c00]

%include "hexprint.asm"

mov bx, 0x1234
call hexprint

jmp $ ; Jump forever.

; Padding and magic BIOS number.
times 510-($-$$) db 0
dw 0xaa55

hexprint.asm

hexprint:
    mov ah, 0x0e  ;set bios to teletype mode
    mov al, bl    ;move the value from bl to al, (0x34)
    int 0x10      ;make bios print
    ret

1 Ответ

1 голос
/ 27 марта 2020

Проблема не в функции, а в том, как работает сборка. Машина запускается в верхней части файла и движется вниз. Включение файла в начало файла немедленно «запускает» содержимое, вызывая много странностей. Переместите оператор include ниже бесконечного l oop, но выше отступа, чтобы он a) был доступен только при вызове и b) не выходил за пределы того, что может видеть загрузчик без настройки чтения с диска

...