首页 > 解决方案 > 使用 ld 链接已编译的程序集和 C 文件

问题描述

我已经编译了这些程序:

  BITS 16
extern _main
start:
      mov ax, 07C0h 
      add ax, 288
      mov ss, ax 
      mov sp, 4096

      mov ax, 07C0h 
      mov ds, ax 

      mov si, text_string 
      call print_string 

      jmp $

      text_string db 'Calling Main Script'
      call _main

print_string:
      mov ah, 0Eh 

.repeat:
      lodsb 
      cmp al, 0
      je .done 
      int 10h
      jmp .repeat 

.done:
      ret 

      times 510-($-$$) db 0
      dw 0xAA55

这是一个测试,只是为了尝试链接它们

int main()
{
  return 0;
}

两者都可以自己编译完全正常使用: gcc -Wall -m32 main.c nasm -f elf bootloader.asm 但是我无法使用链接它们: ld bootloader.o main.o -lc -I /lib/Id-linux.so.2 并且我收到此错误:

ld: i386 architecture of input file `bootloader.o' is incompatible with i386:x86-64 output
ld: i386 architecture of input file `main.o' is incompatible with i386:x86-64 output
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
ld: bootloader.o: file class ELFCLASS32 incompatible with ELFCLASS64
ld: final link failed: file in wrong format

任何帮助都会非常感谢

标签: clinuxgccassemblynasm

解决方案


GCC 默认已经动态链接libc,所以如果你想手动链接ld,请确保你的 ELF 可执行static,你可以通过-static标志传递。

gcc -o <filename> <filename>.c -static -Wall -m32然后链接ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o <filename> -lc <filename>.o

我想,由于像 NASM 这样的汇编程序具有静态(不带 的独立libc),您可以使用 直接使 ELF 动态可执行,您可以使用标志libc传递。-dynamic-linker

例如 :

x86

nasm -f elf32 -o <filename>.o <filename>.asm
ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o <filename> -lc <filename>.o

x86_64

nasm -f elf64 -o <filename>.o <filename>.asm
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o <filename> -lc <filename>.o

推荐阅读