Как скомпилировать и связать C и ASM вместе в Windows для моей ОС
У меня проблема с моим 32-битным защищенным режимом ОС проекта Sinatra. Я могу скомпилировать исходники в объектные файлы, но я не знаю, как связать их вместе. Я использую NASM и TDM-GCC на Windows. Я исправил проблемы с моим кодом, поэтому он компилируется. Я удалил комментарии для краткости.
Мой файл boot.asm
:
[BITS 32]
[global start]
[extern _JlMain]
start:
cli
call _JlMain
hlt
Мой файл JSinatra.h
:
#ifndef __SINATRA_H__
#define __SINATRA_H__
#define JWhiteText 0x07
void JlMain();
void JlClearScreen();
unsigned int JlPrintF(char * message, unsigned int line);
#endif
Мой файл JSinatra.c
:
#include "JSinatra.h"
void JlClearScreen() // clear entire screen
{
char * vidmem = (char * ) 0xb8000;
unsigned int i = 0;
while (i < (80 * 25 * 2)) {
vidmem[i] = ' ';
i += 1;
vidmem[i] = JWhiteText;
i += 1;
}
}
unsigned int JlPrintF(char * message, unsigned int line) {
char * vidmem = (char * ) 0xb8000;
unsigned int i = 0;
i = line * 80 * 2;
while ( * message != 0) {
if ( * message == '\n') {
line += 1;
i = (line * 80 * 2); * message += 1;
} else {
vidmem[i] = * message; * message += 1;
i += 1;
vidmem[i] = JWhiteText;
i += 1;
}
}
return (1);
}
void JlMain() {
JlClearScreen();
JlPrintF("Sinatra v0 Virgin/Kernel Mode\n", 0);
}
Мне нужно загрузить мою ОС, начиная с абсолютного адреса 0x100000
, Как правильно скомпилировать и связать мой код для создания бинарного изображения?
2 ответа
Использование GCC-TDM и NASM в Windows
Поскольку вы нацелены на ОС, загружаемую по абсолютному адресу без C-runtime, вам необходимо убедиться, что вы компилируете как автономный код; что ваши файлы asm и C предназначены для объектов одного типа (win32/PECOFF); и последним шагом будет преобразование файла PECOFF в двоичное изображение.
Для компиляции файлов C вы должны использовать что-то вроде:
gcc -m32 -ffreestanding -c JSinatra.c -o JSinatra.o
Для сборки файлов asm вы должны использовать что-то вроде:
nasm -f win32 boot.asm -o boot.o
Чтобы связать их вместе, вы должны сделать это в два этапа:
ld -m i386pe -T NUL -o sinatra.tmp -Ttext 0x100000 boot.o JSinatra.o
ld
Команда выше создаст временный файл sinatra.tmp
это 32-битный исполняемый файл PECOFF. Затем вам нужно конвертировать sinatra.tmp
в двоичное изображение с помощью команды вроде:
objcopy -O binary sinatra.tmp sinatra.img
Затем вы должны иметь двоичное изображение в файле sinatra.img
Прежде всего, если вы компилируете в ELF, вы не должны добавлять начальное подчеркивание перед функциями в сборке.
Теперь, чтобы связать различные исходные файлы вместе, вы, очевидно, должны найти их общий язык, который в данном случае является объектным кодом.
Итак, что вы будете делать:
- Соберите исходные файлы сборки в объектный код.
- Компилировать, но не связывать исходные файлы Си с объектным кодом. В gcc:
gcc -c file.c -o file.o
- Свяжите их вместе. В gcc:
gcc cfile.o asfile.o -o app