Как исправить ошибку «Бесконечный цикл при переходе на C-код из загрузчика» - PullRequest
0 голосов
/ 03 января 2019

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

Хотя мой загрузчик работает правильно, проблема возникает, когда мой загрузчик переходит к коду ядра, написанному на C как программа a.COM. Главное, что фиктивный код просто продолжает печатать символ снова и снова, хотя код должен запускаться только один раз. Кажется, будто основной код вызывается снова и снова. Вот код для startpoint.asm заголовка сборки и bootmain.cpp файла.


Вот код для startpoint.asm, который используется при первом связывании, чтобы код мог быть вызван автоматически. (Написано в MASM )

Примечание: Код загружается по адресу 2000H:0000H.

;------------------------------------------------------------
.286                 ; CPU type
;------------------------------------------------------------
.model TINY               ; memory of model
;---------------------- EXTERNS -----------------------------
extrn        _BootMain:near     ; prototype of C func
;------------------------------------------------------------
;------------------------------------------------------------   
.code   

main:
        jmp short start     ; go to main
        nop

;----------------------- CODE SEGMENT -----------------------
start:  
        cli
        mov ax,cs               ; Setup segment registers
        mov ds,ax               ; Make DS correct
        mov es,ax               ; Make ES correct
        mov ss,ax               ; Make SS correct        
        mov bp,2000h
        mov sp,2000h            ; Setup a stack
        sti
                                ; start the program 
        call           _BootMain
        ret

        END main                ; End of prog

Код для bootmain.cpp

extern "C" void BootMain()
{
    __asm
    {
         mov ah,0EH
         mov al,'G'
         int 10H
    } 
    return;
}

Команды компиляции и компоновщика следующие:

Код для компиляции bootmain.cpp:

CL.EXE /AT /G2 /Gs /Gx /c /Zl bootmain.cpp

Код для компиляции startpoint.asm:

ML.EXE /AT /c startpoint.asm

Код для связывания их обоих (в сохраненном порядке):

LINK.EXE /T /NOD startPoint.obj bootmain.obj

Ожидаемый результат :

G           

Фактический объем производства:

GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG

1 Ответ

0 голосов
/ 03 января 2019

Присмотритесь ближе к концу start.

start никогда не вызывается - к нему напрямую переходят, и он устанавливает сам стек.Когда _BootMain возвращается, стек пуст;ret в конце start вытолкнет ненужные данные из конца стека и попытается перейти к нему.Если эта память содержит нули, поток программы вернется к main.

Вам необходимо настроить что-то конкретное, что произойдет после возврата _BootMain.Если вы просто хотите, чтобы система зависала после выполнения _BootMain, вставьте бесконечный цикл (например, jmp .) в конец start вместо ошибочного ret.

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

...