如何链接从C代码生成的目标文件,静态库和NASM生成的目标文件?

时间:2018-04-25 14:46:11

标签: c assembly linker dos real-mode

我正在开发一个程序(用于真实模式),该程序由引导加载程序加载到内存中的地址并跳转到它并开始执行程序。问题是我将项目分成两个文件: a.asm (16位asm,NASM语法)和 bc (我使用gcc编译dos(djgpp)) )。另外, b.c 使用了allegro库中的一些函数(我把它作为静态库,.a)。

我的问题是,如何将这3个文件编译并链接在一起?我的第一个想法是:

  1. 使用gcc(带-c标志)编译和组装b.c,结果我得到一个 b.o 文件
  2. 使用NASM(-fbin或..?)组装 a.asm 并获取 a.o
  3. 链接 b.o a.o allegro.a 以获取纯二进制文件(无.exe标头, 没有调试信息等。)
  4. 我尝试了上述方法,但是在第3步,链接器抛出一个错误,指出 ao (由NASM生成的目标文件)的格式无法识别,这可能是因为或者我在组装文件时没有调用正确的标志和选项,或者..

    我想就如何解决这个问题提供一些指导。

    感谢。

1 个答案:

答案 0 :(得分:1)

DJGPP生成的.o文件包含32位(i386)代码,无法直接从16位代码调用。

在DOS下,通常使用DOS extender运行32位代码,该unreal mode切换到32位保护模式,设置内存映射和DOS API转换(即小型蹦床功能,切换回16-调用int 21h DOS API时为位实模式)。然后加载并调用32位代码。

用于在16位和32位模式之间切换的DOS扩展器的轻巧替代品:

  • this answer gcc -m16 .code16gcc)。有关 gcc -m16 的详细信息,请参见Syslinux和其他答案。

  • {{3}}项目的引导程序,其中包含16位程序集(NASM),32位程序集(NASM)和32位C(GCC)代码,并在它们之间进行切换。

要将16位和32位代码链接在一起,可以运行objcopy -O binary func.o func.bin(32位),然后将%incbin "func.bin"添加到16位NASM源文件中。但是,这会中断重定位(因此您将无法使用全局变量)。