【问题标题】:GNU Linker and architecture i386GNU 链接器和架构 i386
【发布时间】:2013-03-19 09:57:52
【问题描述】:

所以我在 OS X 上运行,我想链接两个 Mach-O 对象 i386。

第一个是从 NASM 生成的(它是一个汇编文件)

nasm -f macho -o kernel.o kernel.asm

第二个是从 GCC 生成的

gcc -c -arch i386 screen.c

但是当我尝试链接它们时...

ld -o myprogram screen.o kernel.o

...我收到此错误:

Undefined symbols for architecture i386:
  "print", referenced from:
      start in kernel.o
ld: symbol(s) not found for inferred architecture i386

我不明白为什么,因为我的两个文件是Mach-O object i386

$ file screen.o
screen.o: Mach-O object i386
$ file kernel.o
kernel.o: Mach-O object i386

如果你需要,这里是 kernel.asm

[BITS 32]
EXTERN print
GLOBAL start

start:
    mov  eax, msg
    push eax
    call print
    pop  eax

end:
    jmp end

msg  db 'Hello world!', 10, 0

这里是 screen.c

void putcar(uchar c)
{
    /* Some code here */
}

void print(char *string)
{
        while(*string != 0){
                putcar(*string);
                string++;
        }
}

【问题讨论】:

  • 您以前从来没有好奇过挖掘二进制文件吗? :)

标签: c macos assembly ld i386


【解决方案1】:

您需要在 asm 文件中使用符号 _print,即

start:
    mov  eax, msg
    push eax
    call _print
    pop  eax

这是因为 C 函数名称在编译时带有前导下划线。

【讨论】:

  • 谢谢,它有效!只是一个小问题:如何将“ld”输出转换为二进制?
  • “二进制”是什么意思?它已经是一个二进制可执行文件。你想要人类可读格式的二进制文件吗?
  • 在我需要链接两个文件之前,我只是这样做了:nasm -f bin -o kernel kernel.asm,我用x86 boot sector 连接输出,但现在输出是Mach-O executable i386 文件。 ..
  • 好的 - 仍然不清楚你想要达到什么目标 - 也许你应该发布一个单独的问题,更详细一点,因为这与你原来的问题确实是一个不同的问题。
  • -oformat binary (如果 Macho ld 像 Linux ld 一样工作......它可能不会)。您可能需要使用-T text=0x7D00 (或您的引导扇区加载它的任何位置)指定一个“原点”。我认为“objcopy”也会这样做(?)。 osdev.org 可能对此有所了解...
猜你喜欢
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-02
  • 1970-01-01
相关资源
最近更新 更多