3

只有两个文件,main.ckernel.asm,我尝试使用 NASM 和 GCC 与它们一起制作程序。内容如下:

主程序

#include <stdio.h>

void Print_String() {
    printf("Hello World!\n");
}

内核文件

extern Print_String

[section .text]
global _start
_start:
    call Print_String

编译和链接:

nasm -f elf -o kernel.o kernel.asm
gcc -c -o main.o main.c
ld -s -lc -o final kernel.o main.o

然后我final用命令运行文件:./final,但结果令人沮丧:

bash: ./final: No such file or directory

但是,当前目录确实有文件final,对于命令ls,它显示:

final  kernel.asm  kernel.o  main.c  main.o

那么为什么它找不到文件final呢?有什么问题吗?任何帮助表示赞赏!

4

3 回答 3

4

它本身并不是找不到它。错误消息有些误导。动态链接器无法解析其依赖关系,因此您的程序映像不可加载(并且不可执行)

问题是您在没有任何其他工具的情况下动态链接 libc 以使动态链接真正起作用。因此,您将得到一个无法加载的二进制图像。

您可能会发现静态链接 libc 更容易。这可以按如下方式完成:

ld -Bstatic -o final kernel.o main.o -lc

请注意,您必须在使用它的代码模块 main.o 之后移动“-lc”位。

如果你试试这个,你会得到一大堆未解析的符号。那是因为您还需要链接 libgcc 和 libgcc_eh。

以下让我非常接近(抱歉,在这里使用 64 位系统):

ld -L/usr/lib/gcc/x86_64-linux-gnu/4.4.3/32/ -melf_i386 -Bstatic -lc -o final kernel.o main.o -lc -lgcc -lgcc_eh

这对我来说失败了

/usr/lib/gcc/x86_64-linux-gnu/4.4.3/32//libgcc_eh.a(unwind-dw2-fde-glibc.o): In function `_Unwind_Find_FDE':
(.text+0x193b): undefined reference to `dl_iterate_phdr'

这没有多大意义。在 32 位系统上链接 32 位可能会更幸运。

更新

为上面的闲聊道歉。我再次考虑了这一点,当然,可以使动态链接工作。缺少的部分是指定动态链接器:

就我而言,这是:

ld -dynamic-linker /lib32/ld-linux.so.2 -melf_i386 -o final kernel.o main.o -lc

所以对你来说,以下应该工作:

ld -dynamic-linker /lib/ld-linux.so.2 -o final kernel.o main.o -lc

再次更新

作为对 markzar 评论的回应 - 您必须进行系统调用才能干净地退出。这具有在 C 中执行类似于 exit(0) 的效果:

mov eax,1  ; Syscall #1       
mov ebx,0  ; Return code 0 = success
int 80H
于 2013-02-14T04:47:43.403 回答
1

尝试这个。首先更改 kernel.asm 如下:

extern Print_String

[section .text]
global main
main:
    call Print_String

然后使用以下命令创建可执行文件(而不是链接器)。

nasm -f elf -o kernel.o kernel.asm
gcc -c -o main.o main.c
gcc -o final kernel.o main.o
于 2013-02-14T05:26:55.587 回答
0

非常简单:程序中没有main()可调用的内容……因此,无论您做什么,C 程序启动机制都不会得到控制。

于 2013-02-19T17:00:17.813 回答