编译汇编代码
我正在尝试编译我用 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:
I'm trying to compile an ASM program I wrote with NASM and the "ld" command from DJGPP. This is the code for the batch file I'm using to compiling it:
@echo off
set path=C:\NASM;%PATH%
nasm -f aout -o start.o start.asm
ld -T link.ld -o kernel.bin start.o
But when I run the file I get:
start.o: file not recognised: File format not recognized
What, in my build file, have I done wrong to cause this error message?
EDIT
This is my link.ld file:
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 = .;
}
EDIT
Nothing else is working, so here is the code for my ASM file (I was creating kernel for an Operating System I've been working on):
[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:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您在代码文件中缺少文本部分:
对于对象格式,请尝试
-f coff
因为这似乎是 DJCPP 的正确格式(感谢@ninjalj):我没有为您提供 DJCPP 的解决方案,但我能够在 64 位 Linux 上编译并链接它(添加了
.text
部分),如下所示:You are missing text section in the code file:
For the object format try
-f coff
since that seems to be the right format for DJCPP (thanks @ninjalj):I have no solution for you for DJCPP, but I was able to compile and link this on my 64-bit Linux (with added
.text
section) as follows:您尝试过 nasm -f coff 吗?
从 nasm -hf 输出:
Have you tried nasm -f coff?
From nasm -hf output:
根据多重引导标头信息以及该文件链接为二进制格式输出(如链接描述文件中指定)的事实来看,告诉我这是一个操作系统内核(或至少是一个学术示例),因此意味着要以独立模式编译和运行,而不是常规用户空间进程(需要内核来管理)。
ld 默认接受 elf 格式(它在很大程度上取代了 UNIX 平台上旧的、过时的 aout 格式),您可能必须在链接器脚本中指定 aout 作为输入格式(或者告诉 nasm 输出 elf 格式目标文件)。 multiboot 与 elf 配合使用效果最好,并且不需要所有“aout_kludge”。
该代码(或任何内核代码)的执行方式是由引导加载程序加载。由于这是一个兼容多重引导的内核,因此它应该由兼容多重引导的引导加载程序(例如 grub)加载(请参阅 http://www.gnu.org/software/grub/)。
我知道您使用的是 Windows,因此您的站点上可能没有正确安装信息文档系统,但您可以阅读 GNU 文档,网址为 http://www.gnu.org/software/grub/manual/multiboot/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
Judging by the multiboot header information, and the fact that this file is linked into a binary format output (as is specified in the linker script), tells me that this is an operating system kernel (or at least an academic example of one), and is therefore meant to be compiled and run in freestanding mode, and not a regular user space process (which requires a kernel to manage).
ld by default accepts the elf format (which very much replaces the old, obsolete aout format on unix platforms), you might have to specify aout as an input format in the linker script (or alternatively tell nasm to output elf format object files). multiboot works best with elf and does not require all that "aout_kludge"
The way this code (or any kernel code) was meant to be executed is by being loaded by a boot loader. As this is a multiboot compliant kernel, it was meant to be loaded by a multiboot compliant boot loader such as grub (see http://www.gnu.org/software/grub/).
I realize you are on windows, so you probably don't have the info documentation system properly installed at your site, but you can read read the GNU documentation at http://www.gnu.org/software/grub/manual/multiboot/multiboot.html . Also it looks like this code was meant to be compiled on a unix like platform, so at least you are right to use djgpp (gcc ported to windows).
As I am working on GNU/Linux, it is hard for me to debug whatever MS windows or djgpp issues need to be worked around, perhaps the GNU ld (part of binutils) info documentation would be helpful - http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_toc.html