Простая «загрузочная программа» NASM не правильно обращается к памяти? - PullRequest
5 голосов
/ 11 июля 2011

** Обратите внимание, что когда я говорю «загрузочная программа», я не имею в виду программу, загружающую ОС.Я имею в виду простую программу, которая запускается, когда вы запускаете компьютер и что-то делаете.

Хорошо, поэтому я не очень хорошо разбираюсь в Assembly / NASM, но я думаю, что яЯ достаточно хорошо разбираюсь в этом, чтобы писать простые загрузочные программы.

Ну, я подумал Я достаточно хорошо понялВидимо, нет.

Я попробовал простую загрузочную программу, которую я нашел в Интернете.Он работал нормально (печатает букву «А»).Затем я изменил его, чтобы напечатать письмо, хранящееся в памяти.Это не удалось;вместо того, чтобы печатать «А», он печатает смайлик.(Клянусь, компьютер смеется надо мной прямо сейчас.)

Это код из исходного файла:

[BITS 16]    ; We start up in 16-bit real mode
[ORG 0x7C00] ; We're booted into memory at this address. (Or so I'm told)

mov ah, 0x0E       ; Teletype command
mov bh, 0x00       ; Page number
mov bl, 0x07       ; Attributes (7 == white foreground, black background)
mov al, [testChar] ; Character to print; load it from the memory referenced by testChar.

int 0x10  ; Tell the BIOS to execute the teletype command.

jmp $  ; Infinite loop prevents us from going off and executing the other junk in memory

testChar db 65  ; This is the character we want to print. 'A'.

; The following code pads the rest of the outputted binary file
;   and concludes it with the bootloader signature so I don't have
;   to do so manually.
times 510-($-$$) db 0
dw 0xAA55

Если я заменю ' move al, [testChar] 'с' move al, 65 ', буква' A 'печатается правильно.Я попытался переместить объявление памяти, я попробовал каждую комбинацию скобок или нет скобок вокруг BITS и ORG, и я попытался увеличить или уменьшить testChar (то есть [testChar + 1]).Каждый раз он печатает либо смайлик, обратный смайлик (когда я увеличиваю testChar), либо вообще ничего (когда я помещаю объявление памяти перед кодом, вероятно, потому что код не выполняется = P).Я не могу заставить эту чертову работу работать.

Теперь, для спецификаций (потому что они, вероятно, актуальны):

  • Я использую Dell Latitude CPiс процессором Intel Pentium II, потому что это все, что я должен тестировать (я не тестирую ассемблер на моем обычном компьютере. Черт, нет.)Я почти уверен, что процессор x86, так как я использую Windows XP, Ubuntu и Arch Linux на нем.

  • В настоящее время я пишу и компилирую программы на Arch Linux, используяNASM.

  • Программа загрузки запускается с дискеты

  • Я использую ' nasm -f bin FILENAME 'для компиляции кода.

  • Затем я использую команду «mformat» из пакета «mtools» для AL, чтобы перенести скомпилированную загрузочную программу на дискету через' mformat -f 1440 -B BOOTPROGRAM A: '.

Итак, что я облажался на этот раз?Или это проблема с моим процессором / BIOS?

Ответы [ 3 ]

3 голосов
/ 11 июля 2011

DS, вероятно, заполнен каким-то мусорным значением, поэтому просто сделайте:

push cs
pop ds

или

mov ax, cs
mov ds, ax
mov es, ax

Еще лучше, не доверяйте CS и делайте:

xor ax, ax
mov ds, ax

См. это обсуждение : некоторые BIOS могут использовать 07c0: 0000 вместо традиционного 0000: 7c00, особенно при загрузке с CD-ROM с использованием ElTorito.

0 голосов
/ 27 июня 2013

Он работал нормально, когда я запускал его в первый раз! Он печатает «А». Используйте команду nasm [filename.asm] -o [filename.com] -l [filename.lst]

Я использовал nasm OSbad.asm -o OSbad.com. Использовал MagicISO для создания загрузочного образа файла OSbad.iso и для записи дисков Windows на DVD / RW. Загрузил Oracle VM и создал новую виртуальную машину с 256 МБ ОЗУ, CD / DVD, жестким диском объемом 2 ГБ. Загружается с DVD и печатает «А» на экране.

Так что, я думаю, ваша программа работает. Должно быть, другие вещи, которые вы делаете, делают его неработоспособным.

0 голосов
/ 12 июля 2011

Это создает следующий код (просто запустите objdump для вашего скомпилированного кода).

00000000  B40E              mov ah,0xe
00000002  B700              mov bh,0x0
00000004  B307              mov bl,0x7
00000006  A00D7C            mov al,[0x7c0d]
00000009  CD10              int 0x10
0000000B  EBFE              jmp short 0xb
0000000D  41                inc cx ; this is actually your testChar
                                   ; ignore the opcode translation

Теперь, если вы находитесь в 0x7C00, тогда [0x7c0d] будет последним байтом в этом (то есть 0x41или 65, или ASCII "A").Но если, как один из других авторов (ninjalj), упомянул, что у вас есть странная ошибка биоса, которая означает, что вы не находитесь в 0x7C00, тогда [0x7c0d] - чье-то предположение.

...