在linux下混合编程和C语言

只有两个文件, main.ckernel.asm ,我试图用NASM和GCC kernel.asm一个程序。 内容如下:

main.c中

 #include <stdio.h> void Print_String() { printf("Hello World!\n"); } 

kernle.asm

 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 ? 有什么不对的吗? 任何帮助感激!

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

问题是你动态链接反对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 

尝试这个。 首先改变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 

非常简单:在程序中没有main()函数调用…因此无论你做什么,C程序启动机器都不会被占用。