Почему этот код загрузчика не работает? - PullRequest
2 голосов
/ 18 апреля 2011

Я ожидаю, что он напечатает строку, но ничего не распечатывается.Когда я делаю строку короче, она иногда работает, а когда я делаю их снова больше, она иногда работает.

Я не знаю, почему это не работает.

Может кто-нибудь помочьмне?Спасибо.

Используемый код сборки:

(Emacs 23, Ubuntu 10.10, nasm, VirtualBox OSE)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org 0x7c00
bits 16
str:
    db "Some say the world will end in fire",10,13
    db "Some say in ice",10,13
    db "From what I've tasted of desire",10,13
    db "I hold with those who favor fire",10,13
    db "But if I had to perish twice,",10,13
    db "I think I know enough of hate",10,13
    db "To say that for destruction ice",10,13
    db "is also great and would suffice."
    db "Robert Frost - Fire and Ice"
    db 0
start:
    xor ax,ax
    mov ds,ax
    mov es,ax
    mov si, str
    xor bx,bx
    mov ah, 0x0e
print:
    lodsb   ;al = current char
    cmp al, 0
    je end
    int 0x10
    jmp print
end:    
    cli
    hlt

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

Ответы [ 2 ]

9 голосов
/ 18 апреля 2011

Потому что он начинает выполнять код прямо по инструкции на 7c00. Это, к сожалению, где у вас есть строка.

Перед этой строкой должна стоять инструкция jmp, чтобы она перешла на start.

Обычно это короткий прыжок EB xx, за которым следует NOP 90. Некоторые BIOS могут настаивать на том, что он имеет такую ​​форму, даже если это не имеет большого значения для процессора.

Другими словами, вы бы искали что-то вроде:

org 0x7c00
bits 16
realstart:
    jmp short start
    nop
str:
    db "Some say the world will end in fire",10,13
    :
    db "Robert Frost - Fire and Ice"
    db 0
start:
    xor  ax,ax
    :

Просто имейте в виду, что короткий прыжок ограничен тем, какое расстояние он может пройти, примерно +/- 128 байт, поэтому размер вашей строки будет обязательно ограничен этим. Если ваш BIOS не требует формата EB xx 90, вы можете просто сделать обычный переход.

Другая вещь, которую вы можете попробовать, - переместить всю строку после инструкции hlt:

org 0x7c00
bits 16
start:
    xor  ax,ax
    :
end:    
    cli
    hlt
str:
    db "Some say the world will end in fire",10,13
    :
    db "Robert Frost - Fire and Ice"
    db 0

но, опять же, это зависит от того, что в BIOS не требуется комбо jmp/nop при запуске.

1 голос
/ 16 мая 2011

Хороший способ убедиться, что paxdiablo и Игорь Скочинский верны, - это поместить текстовую строку в файл, а затем запустить ее на дизассемблере. Более короткие строки, которые печатаются правильно, должны разбираться в строку кода, которая ничего не повредит. Более короткие строки, которые терпят неудачу, и более длинная строка будет содержать недопустимые инструкции, инструкции перехода или вызова, или даже просто иметь 2- или 3-байтовую инструкцию в конце, которая съедает код операции для инструкции "xor ax,ax" в начале вашего кода.

...