Как сгенерировать RAW BIN с объявленным смещением сегмента с помощью WatCom
Я написал загрузчик в NASM, который загружает данные программы объемом 64 КБ с диска в память по адресу 0060:0000 [SEG:OFF]. Я протестировал эту часть своего проекта, написав некоторый код в Assembly (NASM) и поместив его на диск. Работает отлично!
Полный проект немного сложен для написания на ассемблере. Поэтому я решил, что буду использовать C с встроенной сборкой для дальнейшего. Для этого я загружаю среду open-watcom-c-win32-1.9. У меня есть простой C-код для тестирования некоторых директив компилятора и компоновщика WatCom для создания файла RAW BIN. Файл bin создается, но не запускается после загрузки моего загрузчика в память. Я пробую много директив wlink для установки значений сегмента и смещения, но это не работает.
void main()
{
__asm
{
mov ah, 0x0E
mov al, '!'
int 0x10
}
}
Я думаю, что проблема в том, что компилятор и компоновщик используют неправильные адреса сегментов и смещений при генерации кода. Потому что Wlink отбросит следующую ошибку в любом случае.
Предупреждение! W1023 начальный адрес не найден, используется 0000:0000
Я не знаю, как я могу правильно установить адреса смещения сегмента, но это было бы ненужно для работающей программы. Мои вопросы о том, какие директивы WatCom я использую для создания 16-битного файла RAW BIN реального режима из исходного кода C с объявленным сегментом: смещением? Это возможно с WatCom или мне нужно использовать другие вещи?
1 ответ
Так как порядок функций C является несколько непредсказуемым, в конкретной точке входа необходим специальный код инициализации. В этом случае точка входа всегда находится в самом начале файла. Закодированное смещение этого исходного кода также определяет смещение всех других адресов (segemnt не имеет значения, и компилятор не делает никаких предположений по этому поводу). Вы, вероятно, захотите написать свой очень тонкий исходный код. Код инициализации по умолчанию находится в файле cstart_t.obj, поэтому его нужно заменить. То, что вам нужно поместить туда, зависит от того, что вам нужно, если компоновщик жалуется на какой-то пропущенный символ, вам может понадобиться добавить его туда. Такой минимальный, как этот, будет работать с вашим примером кода, но может сделать некоторые функции C непригодными (написано в синтаксисе Nasm):
global __STK
extern main_ ; The actual name of the main function depends on the memory model I think.
section _INIT class=CODE
resb 0 ; The expected offset of the code.
..start:
jmp main_ ; Don't expect main() to return.
section _STACK stack class=STACK
__STK:
group DGROUP _INIT _STACK