2013-07-17 3 views
0

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

org 100h 

start: 
xor ax, ax 
mov es, ax ; ES <- 0 
mov cx, 1  ; cylinder 0, sector 1 
mov dx, 0080h ; DH = 0 (head), drive = 80h (0th hard disk) 
mov bx, buff ; segment offset of the buffer 
mov ax, 0201h ; AH = 02 (disk read), AL = 01 (number of sectors to read) 
int 13h 

jnc .read 

.read: 
    mov  ax, cs ; set up segments 
    mov  ds, ax 
    mov  es, ax 
    mov  al, 03h 
    mov  ah, 0 
    int 10h 

mov  si, buff 
call print_string 

.done: 
jmp  .done 


print_string: 
lodsb  ; grab a byte from SI 

test al, al ; logical or AL by itself 
jz  .done ; if the result is zero, get out 

mov  ah, 0x0E 
int 0x10  ; otherwise, print out the character! 
jmp  print_string 
.done: 
ret 

buff dw 512 

Моя среда исполнение DosBox0. 70 и exe файл .COM. Я ожидаю увидеть 512 байт на экране, но когда я запустил свой .COM-файл, его просто пустой экран. Есть несколько причин, которые я мог видеть за ним.

1) Дается код, который не возвращается из прерывания Bios должным образом (int 13h). 2) Строка должна заканчиваться нулем, что здесь не происходит.

Но не уверен, что это причины, по которым это происходит, и если да, то как я могу реанимировать тезисы вопросов?

+0

Попробуйте 'mov bx, offset buff' –

+0

@EgorSkriptunoff: Код выглядит так, как будто он был написан для NASM, у которого нет/требуется ключевое слово' offset'. – Michael

+0

Весьма вероятно, что загрузочный сектор содержит байты, которые выходят за пределы диапазона печати в таблице ASCII (и что он содержит байты со значением 0).Вместо использования функции print_string попробуйте написать функцию, которая печатает каждый байт в виде двух шестнадцатеричных цифр и повторяет это 512 раз. Кстати, вы заявили, что ваш буфер имеет место для 1024 байта (512 слов). – Michael

ответ

3

Загрузочный сектор диска содержит не ASCII-данные, а код. С большой вероятностью один из первых байтов будет NULL и останется, возможно, не пригодным для печати кодом (например, CR, LF и т. Д.).

Попытка распечатать буфер INT 10h, который печатает коды ascii и заканчивается на 0, приведет, вероятно, к тому, что ничего не отображается вообще.

Вы должны преобразовать каждый байт буфера в шестнадцатеричную строку и затем напечатать эти строки на дисплее. Таким образом вы получите простой шестнадцатеричный дамп загрузочного сектора.

+0

Спасибо @johnfound за ваш ответ. Одна вещь хотела бы знать, если первый байт MBR равен нулю, тогда нельзя распечатать его, чтобы отображать с помощью int10h, даже если его в шестнадцатеричном формате. Это правильно? –

+0

Конечно, если вы перестанете печатать на байте 0, тогда да, но если вы хотите сделать шестнадцатеричный дамп, вы должны просто распечатать все 512 байт сектора. – johnfound

+0

Johanfound вы хотели бы сказать что-нибудь о комментариях Фрэнка относительно того, чтобы оставить es так, как есть? –

1

Dos загружает файл .com в какой-либо сегмент своего выбора и устанавливает ds и es в этот сегмент. Ваш buff находится в этом сегменте, а не в сегменте 0! Вы читаете первый сектор для сегмента 0, который, вероятно, сгибает ваш IVT. Оставьте es самостоятельно.

После прочтения одного сектора вы проверяете флаг переноса (указывающий на ошибку), но оставьте его в .read независимо от того, установлено оно или нет. Если ошибка, вы, вероятно, захотите сбросить диск и попробовать прочитать снова. Вероятно, вам понадобится «счетчик повторов», поэтому вы не зайдете в бесконечный цикл.

Ваш buff не содержит 512 байт, но два байта со значением 512. Так как это в конце вашего файла, это, вероятно, не повредит, но это не «правильно».

Успешно прочитав сектор, вы можете напечатать его как символы ascii, но вы хотите напечатать все 512 байт, а не останавливаться на первом 0, с которым вы сталкиваетесь. Вероятно, шестнадцатеричный дамп был бы более читабельным.

Если первый байт вашего MBR равен нулю, мы находимся в глубокой мутной воде! Первый байт действительного ботинок должен быть коротким jmp, за которым следует nop, или около jmp. Мы немного неудобны в том, чтобы начинать сапоги таким образом, и большинство BIOS не проверяют, но это то, что «предполагается» там. Что бы CPU выполнил, если он увидел 0 в качестве первого байта? (подсказка: это add)

Я думаю, что ваши две основные проблемы устанавливают es в ноль и останавливают печать, если встречается нуль. Попробуйте снова. FFS, не пытайтесь писать что-либо на свой диск, пока не получите надежную работу чтения!

+0

Спасибо, Фрэнк, точка, которую вы сделали в отношении «вы проверяете флаг переноса (указываете на ошибку), но входите в .read». То, как я это делаю, я проверяю, прошел ли мой сектор чтения хорошо, тогда он очистит перенос флаг и команда jnc совершают короткий прыжок, если флаг переноса ясен, я делаю неправильно здесь? –

+0

Нет, вы в порядке, если флаг флага ясен. Но если флаг переноса установлен, вы все равно переходите к '.read:'. Это не наносит большого вреда, но ваш bootsector не будет в «buff». –

+0

Фрэнк Фрэнк. У тебя есть точка. Но точка, по-прежнему вызывающая неприятности, оставляет только одну (не устанавливая на ноль). Не могли бы вы рассказать мне более подробно? –

Смежные вопросы