2012-06-01 2 views
2

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

; This is NASM 

     BITS 16     ; 16 bits! 

start:       ; Entry point 
     mov ax, 07C0h   ; Move the starting address (after this bootloader) into 'ax' 
     add ax, 288    ; Leave 288 bytes before the stack beginning for some reason 
     mov ss, ax    ; Show 'stack segment' where our stack starts 
     mov sp, 4096   ; Tell 'stack pointer' that our stack is 4K in size 

     mov ax, 07C0h   ; Use 'ax' as temporary variable for setting 'ds' 
     mov ds, ax    ; Set data segment to where we're loaded 


     mov si, text_string  ; Put string position into SI (the reg used for this!) 
     call print_string  ; Call our string-printing routine 

     jmp $     ; Jump here - infinite loop! 

     text_string db 'This is my cool new OS!', 0 ; Our null terminated string 
                ; For some reason declared after use 


print_string:     ; Routine: output string in SI to screen 
     mov ah, 0Eh    ; I don't know what this does.. 
           ; Continue on to 'repeat' 
.repeat: 
     lodsb     ; Get character from DS:SI into AL 
     cmp al, 0    ; If end of text_string 
     je .done    ; We're done here 
     int 10h     ; Otherwise, print the character (What 10h means) 
     jmp .repeat    ; And repeat 

.done: 
     ret 

     times 510-($-$$) db 0 ; Pad remainder of boot sector with 0s 
     dw 0xAA55    ; The standard PC 'magic word' boot signature 

Спасибо,

Джо

ответ

1

Ваши комментарии в основном верны.

mov ah,0Eh

Это устанавливает параметр вызова прерывания BIOS:

int 10h

Посмотреть here для получения более подробной информации, но по существу вызов 10h ожидает работа в ah и данные для операции в al.

Регистры сегментов не могут быть загружены напрямую и могут загружаться только из регистра, поэтому использование ax в качестве «временной переменной».

288 байт, добавленных в указатель базового стека, фактически не являются байтами. Адреса, загруженные в регистры сегментов, фактически указывают на 16-байтовые блоки, поэтому для преобразования числа в его фактический адрес сдвиньте его на 4 бита. Это означает, что адрес 07C0h на самом деле относится к 7C00h, где размещается ваш код загрузчика. 288 - это 120h в гексагоне, и поэтому фактическое местоположение стека действительно 7C00h + 1200h = 8E00h.

Кроме того, вы используете такие слова, как «показать» и «рассказать», которые хороши, но лучше подумать об определении стека, установив ss и sp, а не сообщать, где он находится ... Я надеюсь, что это сделает смысл.

+0

О, я вижу, поэтому 4608 байт фактически добавляются к 'ax' , Предположительно 512 из них для самого скрипта/программы, а затем 4096 из них используется для чего-то. Используется ли 4096 в качестве дискового буфера или он для самого стека - устанавливается ли «ss» в начало или конец стека? –

+0

@ Joesavage1 SS определяет базу стека, а SP определяет, где в стеке мы находимся. Когда стек пуст, SP указывает на самое высокое смещение от SS. Это означает, что SP фактически уменьшается, когда вещи помещаются в стек и увеличиваются, когда они выскользнули.SP Всегда указывает на последнюю вещь, помещенную в стек – Dougvj

+0

Итак, вы говорите, что это указывает _start_ стека ?! Если да, то почему мы передаем ему место («топор») 4096 байт от места хранения самого кода? (4608 из точки входа вещи) Что это за 4096 байт, если они не для стека? Кроме того, вы знаете, почему «ds» возвращается к 07C0h [7C00h] после того, как материал стека завершен? («Установите сегмент данных туда, где мы загружены») –

0
mov ah, 0Eh    ; I don't know what this does.. 

Загрузка 0eh в ah устанавливает int 10h функции Teletype output, которая напечатает символ в al на экран.

Ваш .repeat цикл загружает каждый символ из text_string в al и звоните int 10h.

+0

Я не так много людей, занимающихся загрузчиком. :-) В этом вопросе есть ответы, объясняющие настройку: http://stackoverflow.com/questions/3231607/stack-segment-in-the-mikeos-bootloader –

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