Компиляция и ссылка на файл .com с Turbo C - PullRequest
2 голосов
/ 01 мая 2019

Я пытаюсь скомпилировать и связать простую программу с файлом DOS .com, используя компилятор и компоновщик Turbo C. Таким образом я пробую простейшую C-программу, о которой я только могу подумать.

void main()
{}

Есть ли аргументы командной строки для ссылки на com-файлы в Turbo C Linker?

Сообщение об ошибке, полученное от компоновщика, выглядит следующим образом:

"Неустранимый: невозможно создать COM-файл: неверный адрес точки входа"

Я знаю, что для com-файлов необходима точка входа в 100 часов. Есть ли у Turbo C возможность установить этот адрес?

Ответы [ 2 ]

1 голос
/ 02 мая 2019

Прошло много времени с тех пор, как я искренне пытался использовать Turbo-C для такого рода вещей. Если вы компилируете и связываете в командной строке отдельно с помощью TCC.EXE и TLINK.EXE, тогда это может работать для вас.

Для компиляции и ссылки на COM-файл вы можете сделать это для каждого из ваших исходных файлов на C, создав для каждого OBJ-файл:

tcc -IF:\TURBOC3\INCLUDE -c -mt file1.c
tcc -IF:\TURBOC3\INCLUDE -c -mt file2.c
tcc -IF:\TURBOC3\INCLUDE -c -mt file3.c

tlink -t -LF:\TURBOC3\LIB c0t.obj file1.obj file2.obj file3.obj,myprog.com,myprog.map,cs.lib

Каждый файл C компилируется индивидуально с использованием -mt (модель с крошечной памятью) в соответствующий файл OBJ. Параметр -I указывает путь к каталогу INCLUDE в вашей среде (измените соответственно). Опция -c указывает TCC компилировать только файл OBJ.

Когда связывание -t говорит компоновщику генерировать COM-программу (а не EXE-файл), -LF:\TURBOC3\LIB - это путь к каталогу библиотеки в вашей среде (измените соответственно). C0T.OBJ - это исполняемый файл C для крошечной модели памяти. Это включает в себя основную точку входа, которую вы пропустили. Затем вы перечисляете все другие файлы OBJ, разделенные пробелом. После первой запятой идет имя выходного файла. При использовании опции -t назовите программу с расширением COM. После второй запятой следует имя файла MAP (вы можете оставить имя файла пустым, если вам не нужен файл MAP). После третьей запятой стоит список библиотек, разделенных пробелами. С крошечной моделью вы хотите использовать маленькие библиотеки моделей. Библиотека C для маленькой модели памяти называется CS.LIB.

Например, если у нас есть один исходный файл с именем TEST.C, который выглядит следующим образом:

#include<stdio.h>

int main()
{
    printf("Hello, world!\n");
    return 0;
}

Если мы хотим скомпилировать и связать это, команды будут:

tcc -IF:\TURBOC3\INCLUDE -c -mt test.c
tlink -t -LF:\TURBOC3\LIB c0t.obj test.obj,test.com,test.map,cs.lib

Вам придется использовать пути для вашей собственной среды. Эти команды должны создать программу с именем TEST.COM. При запуске он должен вывести:

Привет, мир!

0 голосов
/ 01 мая 2019

Ваша проблема связана с "точкой входа"

некоторые компиляторы или компоновщики могут распознавать void main() как точки входа, пропускающие возвращаемое значение, но не все из них.

Вместо этого вы должны использовать int main() точку входа для лучшего контроля над приложением, и компилятор может распознавать основную функцию как точку входа

пример:

int main() {
/* some compiler return 0 when you don't for main,
 they can ask for return value */
}

от geekforgeeks:

Соответствующая реализация может предоставлять больше версий main (), но все они должны иметь возвращаемый тип int. Int, возвращаемый функцией main (), - это способ для программы вернуть значение в «систему», которая ее вызывает. В системах, которые не предоставляют такую ​​возможность, возвращаемое значение игнорируется, но это не делает «void main ()» легальным C ++ или легальным C. Даже если ваш компилятор принимает «void main ()», избегайте его или рискуйте считаются невежественными программистами C и C ++. В C ++ main () не обязательно должен содержать явный оператор возврата. В этом случае возвращаемое значение равно 0, что означает успешное выполнение.

источник: https://www.geeksforgeeks.org/fine-write-void-main-cc/

...