【问题标题】:"Error: bad register name `%rax'" while compiling with MinGW on 64-bit Windows 7在 64 位 Windows 7 上使用 MinGW 编译时出现“错误:错误的寄存器名称 `%rax'”
【发布时间】:2014-01-02 03:21:44
【问题描述】:

在我之前的主题中:How to read registers: RAX, RBX, RCX, RDX, RSP. RBP, RSI, RDI in C or C++? 我询问了有关阅读这些寄存器的问题。现在我写了一个代码来读取(只是现在)RAX 和 RBX。

我正在使用带有 MinGW 作为编译器的 CodeBlocks pm 64 位 Windows 7,并且我正在使用 x86-64 CPU。当我试图编译下面的代码时,我得到了这些错误:

Error: bad register name `%rax'
Error: bad register name `%rbx'

还有代码:

#include <iostream>
#include <cstdlib>
#include <stdint.h>

void read(void)
{
    uint64_t rax = 0, rbx = 0;
    __asm__ __volatile__ (
        /* read value from rbx into rbx */
        "movq %%rbx, %0;\n"
        /* read value from rax into rax*/
        "movq %%rax, %1;\n"
        /* output args */
        : "=r" (rbx), "=r" (rax)
        : /* no input */
        /* clear both rdx and rax */
        : "%rbx", "%rax"
    );

    /* print out registers content */
    std::cout << "RAX = " << rax << "\n";
    std::cout << "RBX = " << rbx << "\n";

}

int main(int argc, char **argv)
{
    read();

    return 0;
}

【问题讨论】:

  • 你正在编译我期望的 32 位代码

标签: c++ mingw x86-64 cpu-registers


【解决方案1】:

我怀疑您的错误来自“clobber”行:

    : "%rbx", "%rax"

应该是:

    : "rbx", "rax"

(哦,别问我为什么!)

编辑:您还需要使用 -m64 或类似工具编译 64 位 - 当然前提是您拥有的 MingW 编译器首先支持 64 位。

【讨论】:

  • 这很奇怪,因为通过这种更改,您的代码可以在我的系统上编译。您在构建时使用的是 64 位模式,对吗?
  • 那么如何设置我的代码块以在 Windows 上以 64 位模式编译它?在我的 Xubuntu 上,我有一些 g++ 标志,但是 Windows 和代码块呢?
  • 我已经很久没有使用 Code::Blocks(过去几年,我所有的开发工作都是针对 Windows 以外的其他平台——过去几年主要是 Linux),但是首先我会在命令行上使用g++ -m64 mycode.cpp。但是,在“项目配置”的某个地方,至少有一个“其他选项”,您可以在其中输入任意内容,添加-m64
  • (当然,由于您实际上并没有破坏 [更改] 寄存器 RAX 和 RBX,因此您实际上不需要在 clobber 列表中的这些寄存器)。
【解决方案2】:

MinGW 是 32 位编译器。它不支持 x86-64 目标,因此您不能使用 RAX 等 64 位寄存器。至少在这个问题之前发生的事情是这样的。我现在不确定 mingw 的情况,但是很长一段时间它都不支持生成 64 位二进制文​​件。此外,它在很多方面都被破坏了,因为它使用了不支持标准 C99 printf 格式说明符或 80 位 long double 的古老 MSVCRT 运行时库。开发人员也不愿意更新或响应(拉取)请求,因此 mingw-w64 被分叉,为 Windows 提供了更完整的解决方案。它解决了所有 printf 问题,对 POSIX 和 Win32 API 提供了更完整的支持,还有更多您可以稍后阅读的内容

如果 mingw 的当前版本确实支持 x86-64,那么您仍然需要传递 -m64 选项 使其输出 64 位可执行文件,因为当我查看their installer 时,mingw 仍然是一个 32 位编译器,默认情况下会编译成 32 位代码,其中 RAX 不存在。另见

但更好的方法是转向更好的编译器,例如 mingw-w64TDM-GCC 或 Clang,它们本机支持 64 位客户机和主机

2005 年,OneVision Software 根据洁净室设计原则创建了 MinGW-w64,因为最初的 MinGW 项目没有提示更新其代码库,包括包含几个关键的新 API 和急需的 64 位支持. 2008 年,OneVision 将代码捐赠给了其主要开发人员之一 Kai Tietz,条件是它仍然是开源的。它首先提交给最初的 MinGW 项目,但因涉嫌使用非公开或专有信息而被拒绝。由于多种原因,MinGW-w64 项目的首席开发者兼联合创始人 Kai Tietz 决定不再尝试与 MinGW 进一步合作。

MinGW-w64 提供了更完整的 Win32 API 实现,包括:

  • 更好的 C99 支持
  • 更好的 POSIX 线程 (pthreads) 支持(包括在 GCC 的 libstdc++ 中启用 C++11 线程相关功能的可能性)
  • GCC multilib,允许用户并行安装 32 位和 64 位库
  • Unicode 入口点 (wmain/wWinMain)
  • DDK(来自 ReactOS)
  • DirectX(来自 Wine)
  • 大文件支持
  • Win64 支持
  • 一些有用的工具,例如 gendef(MinGW 的 pexports 实用程序的改进版本)和 widl(IDL 编译器,MIDL 的免费替代品)。

https://en.wikipedia.org/wiki/MinGW#MinGW-w64

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-31
    • 2014-05-12
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多