【问题标题】:Linking with GCC and x86 ASM in x64 Environment在 x64 环境中与 GCC 和 x86 ASM 链接
【发布时间】:2014-08-22 04:01:14
【问题描述】:

我正在运行 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

我的谷歌搜索引导我为 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 项目编写的汇编代码。

【问题讨论】:

  • 我之前也遇到过同样的问题,我放弃了,开始双启动 Linux。不建议这样做,但希望有人可以帮助您。
  • this mailing list post 看来,我认为您需要使用 32 位 Cygwin 来编译 32 位 x86 可执行文件。
  • 我实际上在 VirtualBox 中运行 amd64 Ubuntu 并且 ELF32 输出也遇到了同样的问题。但是,我需要仔细检查我是否安装了对 GCC 的 x86 支持。

标签: c gcc assembly linker


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2012-01-14
    • 1970-01-01
    • 2013-04-09
    • 2018-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-09
    相关资源
    最近更新 更多