【问题标题】:Compile and Link to .com file with Turbo C使用 Turbo C 编译并链接到 .com 文件
【发布时间】:2019-05-01 14:50:24
【问题描述】:

我正在尝试使用 Turbo C 编译器和链接器编译一个简单的程序并将其链接到 DOS .com 文件。我尝试了我能想到的最简单的 C 程序。

void main()
{}

是否有命令行参数可以链接到 Turbo C 链接器中的 com 文件?

我从链接器得到的错误信息如下:

“致命:无法生成 COM 文件:入口点地址无效”

我知道 com 文件需要入口点位于 100h。 Turbo C 是否可以选择设置此地址?

【问题讨论】:

  • 你有没有运气解决你的问题?
  • 是的,我确实有一些运气。使用 c0t.asm 文件作为入口点并升级到更高版本的 Turbo C 或 C++。
  • 所以我想我的部分回答可能适用于您的情况?

标签: linker dos x86-16 memory-model turbo-c


【解决方案1】:

我已经很久没有真正尝试使用 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 的程序。运行时应打印:

你好,世界!

【讨论】:

    【解决方案2】:

    您可以在使用 IDE 生成 EXE 的同时生成 COM 文件。以下工作于 TC 2.01。在选项中将内存模型更改为Tiny,然后编译程序并生成EXE文件,然后进入命令提示符,运行EXE2BIN PROG.EXE PROG.COM。将 PROG 替换为您的程序名称。

    【讨论】:

      【解决方案3】:

      你的问题是关于“入口点”

      一些编译器或链接器可以识别void main(),例如忽略返回值的入口点,但不是全部。

      您应该使用int main() 入口点来更好地控制应用程序,编译器可以将主函数识别为入口点

      示例:

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

      来自极客:

      一个符合要求的实现可以提供更多版本的 main(),但它们都必须有返回类型 int。 main() 返回的 int 是程序向调用它的“系统”返回值的一种方式。在不提供这种功能的系统上,返回值会被忽略,但这不会使“void main()”合法 C++ 或合法 C。即使您的编译器接受“void main()”,也要避免它,否则会冒险被 C 和 C++ 程序员认为是无知的。 在 C++ 中,main() 不需要包含显式的 return 语句。这种情况下,返回值为0,表示执行成功。

      来源:https://www.geeksforgeeks.org/fine-write-void-main-cc/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-16
        • 2013-09-04
        • 1970-01-01
        • 1970-01-01
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 2021-03-19
        相关资源
        最近更新 更多