3

我正在尝试编译我用 NASM 和来自 DJGPP 的“ld”命令编写的 ASM 程序。这是我用来编译它的批处理文件的代码:

@echo off
set path=C:\NASM;%PATH%
nasm -f aout -o start.o start.asm
ld -T link.ld -o kernel.bin start.o

但是当我运行文件时,我得到:

start.o: file not recognised: File format not recognized

在我的构建文件中,我做错了什么导致此错误消息?

编辑

这是我的 link.ld 文件:

OUTPUT_FORMAT("binary")
ENTRY(start)
phys = 0x00100000;
SECTIONS
{
  .text phys : AT(phys) {
    code = .;
    *(.text)
    *(.rodata)
    . = ALIGN(4096);
  }
  .data : AT(phys + (data - code))
  {
    data = .;
    *(.data)
    . = ALIGN(4096);
  }
  .bss : AT(phys + (bss - code))
  {
    bss = .;
    *(.bss)
    . = ALIGN(4096);
  }
  end = .;
}

编辑

没有其他工作,所以这是我的 ASM 文件的代码(我正在为我一直在研究的操作系统创建内核):

[BITS 32]
global start
start:
    mov esp, _sys_stack
    jmp stublet

ALIGN 4
mboot:
    MULTIBOOT_PAGE_ALIGN    equ 1<<0
    MULTIBOOT_MEMORY_INFO   equ 1<<1
    MULTIBOOT_AOUT_KLUDGE   equ 1<<16
    MULTIBOOT_HEADER_MAGIC  equ 0x1BADB002
    MULTIBOOT_HEADER_FLAGS  equ MULTIBOOT_PAGE_ALIGN | MULTIBOOT_MEMORY_INFO |         MULTIBOOT_AOUT_KLUDGE
    MULTIBOOT_CHECKSUM  equ -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
    EXTERN code, bss, end

    dd MULTIBOOT_HEADER_MAGIC
    dd MULTIBOOT_HEADER_FLAGS
    dd MULTIBOOT_CHECKSUM

    dd mboot
    dd code
    dd bss
    dd end
    dd start

stublet:
    jmp $

SECTION .bss
    resb 8192
_sys_stack:
4

3 回答 3

2

您在代码文件中缺少文本部分:

[BITS 32]
SECTION .text
global start
...

对于对象格式,请尝试-f coff,因为这似乎是 DJCPP 的正确格式(感谢@ninjalj):

-f 的有效输出格式为(`*' 表示默认):
  * bin 平面格式的二进制文件(例如 DOS .COM、.SYS)
    i 英特尔十六进制
    srec 摩托罗拉 S 唱片
    aout Linux a.out 目标文件
    aoutb NetBSD/FreeBSD a.out 目标文件
    coff COFF (i386) 目标文件(例如 DOS 下的 DJGPP)
    elf32 ELF32 (i386) 目标文件(例如 Linux)
    elf ELF(ELF32 的简称)
    elf64 ELF64 (x86_64) 目标文件(例如 Linux)
    as86 Linux as86(bin86 版本 0.3)目标文件
    obj MS-​​DOS 16 位/32 位 OMF 对象文件
    win32 Microsoft Win32 (i386) 目标文件
    win64 Microsoft Win64 (x86-64) 目标文件
    rdf 可重定位动态对象文件格式 v2.0
    ieee IEEE-695(LADsoft 变体)目标文件格式
    macho32 NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) 目标文件
    男子气概 MACHO(MACHO32 的简称)
    macho64 NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) 目标文件
    传递到输出阶段的所有信息的 dbg 跟踪

我没有针对 DJCPP 的解决方案,但我能够在我的 64 位 Linux(带有添加.text部分)上编译和链接它,如下所示:

~$ nasm -f elf64 start.asm
~$ ld -T link.ld -o kernel.bin start.o
于 2010-06-22T03:59:07.080 回答
1

你试过 nasm -f coff 吗?

从 nasm -hf 输出:

coff      COFF (i386) object files (e.g. DJGPP for DOS)
于 2010-06-21T19:42:50.513 回答
0

从多重引导头信息判断,以及这个文件被链接成二进制格式输出的事实(如链接描述文件中指定的那样),告诉我这是一个操作系统内核(或至少是一个学术示例),因此意味着在独立模式下编译和运行,而不是常规的用户空间进程(需要内核来管理)。

ld 默认接受 elf 格式(它在很大程度上取代了 unix 平台上旧的、过时的 aout 格式),您可能必须在链接描述文件中指定 aout 作为输入格式(或者告诉 nasm 输出 elf 格式的目标文件)。multiboot 最适合 elf 并且不需要所有“aout_kludge”

该代码(或任何内核代码)的执行方式是由引导加载程序加载。由于这是一个兼容多重引导的内核,因此它应该由兼容多重引导的引导加载程序(例如 grub)加载(参见http://www.gnu.org/software/grub/)。

我知道您在 Windows 上,因此您可能没有在您的站点上正确安装信息文档系统,但您可以在http://www.gnu.org/software/grub/manual/multiboot阅读 GNU 文档/multiboot.html。而且看起来这段代码是为了在类似unix的平台上编译的,所以至少你使用djgpp(gcc移植到windows)是正确的。

当我在 GNU/Linux 上工作时,我很难调试任何需要解决的 MS windows 或 djgpp 问题,也许 GNU ld(binutils 的一部分)信息文档会有所帮助 - http://ftp.gnu .org/old-gnu/Manuals/ld-2.9.1/html_node/ld_toc.html

于 2012-11-14T17:43:53.227 回答