c - 在 x64 环境中与 GCC 和 x86 ASM 链接

标签 c gcc assembly linker

我正在运行 Windows Ultimate x64 (Core i5),并在 Cygwin 上使用 x64 GCC 编译器。我想通过链接 GCC C 库(通过 Cygwin 安装)来创建一个简单的“Hello, world”程序。我正在使用 NASM 并尝试使用 ELF32 和 Win32 格式来执行以下代码:

;;
;; hello.asm - use the C library to output hello world
;;

; In case I wanted to use the code for Windows later
%if 0
%define main    _main
%define printf  _printf
%endif

global main
extern printf

; we set up our string here
section .data
    formatstr:  db 'hello, world!', 10, 0

section .text

    main:

    sub     esp, 4

    lea     eax, [formatstr]
    mov     [esp], eax
    call    printf

    add     esp, 4
    mov     eax, 0

    ret

使用 nasm -f elf32 hello.asmnasm -f win32 hello.asm 以及 gcc hello.o -o hello 时>,GCC 告诉我:

/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: i386 architecture of input file `hello.o' is incompatible with i386:x86-64 output
collect2: error: ld returned 1 exit status

我的 Google 搜索引导我为 Cygwin 安装 cygwin32 软件包,所以我已经这样做了。

当我查找如何在 32 位模式下运行 GCC 时,我添加了 m32 开关,但这会导致 ELF 和 Win32 产生更多错误输出:

/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3//libgcc_s.dll.a when searching for -lgcc_s
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3/libgcc_s.dll.a when searching for -lgcc_s
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3//libgcc_s.dll.a when searching for -lgcc_s
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3/libgcc_s.dll.a when searching for -lgcc_s
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lgcc_s
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3//libgcc.a when searching for -lgcc
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3//libgcc.a when searching for -lgcc
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3/libgcc.a when searching for -lgcc
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3/libgcc.a when searching for -lgcc
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3//libgcc.a when searching for -lgcc
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3/libgcc.a when searching for -lgcc
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lgcc
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3/../../../libcygwin.a when searching for -lcygwin
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3/../../../libcygwin.a when searching for -lcygwin
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3/../../../libcygwin.a when searching for -lcygwin
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lcygwin
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: cannot find -ladvapi32
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lshell32
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: cannot find -luser32
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lkernel32
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3//libgcc_s.dll.a when searching for -lgcc_s
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3/libgcc_s.dll.a when searching for -lgcc_s
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3//libgcc_s.dll.a when searching for -lgcc_s
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3/libgcc_s.dll.a when searching for -lgcc_s
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lgcc_s
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3//libgcc.a when searching for -lgcc
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3//libgcc.a when searching for -lgcc
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3/libgcc.a when searching for -lgcc
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3/libgcc.a when searching for -lgcc
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3//libgcc.a when searching for -lgcc
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: skipping incompatible /usr/            lib/gcc/x86_64-pc-cygwin/4.8.3/libgcc.a when searching for -lgcc
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: cannot find -lgcc
collect2: error: ld returned 1 exit status

我对汇编器和消化 ABI 还很陌生,所以我不太确定如何继续。我觉得我错过了一些非常简单的东西,因为我已经成功链接了我过去为 C 项目编写的汇编代码。

最佳答案

感谢 Adam Rosenfield 指出了 Cygwin 邮件列表帖子,我继续尝试在考虑 x64 支持的情况下重写我的 ASM。这确实允许我使用 GCC 输出二进制文件。我应该注意到我的程序会导致段错误,但这是我对 x64 汇编器或相应调用约定不够了解的问题。

关于c - 在 x64 环境中与 GCC 和 x86 ASM 链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25439335/

相关文章:

c - C中const的外部链接

c - 如何仅使用 GTK3、C 和 Cairo 制作基本动画

C Makefile 给出具有多个定义的链接器错误

c++ - 模板特化 - MSVC 和 GCC/MinGW 之间的不同行为

assembly - 在软盘镜像文件中使用 grub 在 bochs 中启动您自己的内核

c - 对于 C 开发人员来说,学习 LISP 最快、最不痛苦的方法是什么?

c - 如何减少C中文件指针的值?

C++/调试(AIX 上的 g++)递归快速排序导致段错误

c++ - 在运行时生成机器指令的世界代码?

assembly - 如何使用汇编获取整数输入