在我之前的主题中:How to read registers: RAX, RBX, RCX, RDX, RSP. RBP, RSI, RDI in C or C++?我问过阅读这些寄存器。现在我写了一个代码来阅读(仅供我们使用)RAX和RBX。
我正在使用CodeBlocks pm 64位Windows 7和MinGW作为编译器,我正在使用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;
}
答案 0 :(得分:3)
我怀疑你的错误来自“clobber”行:
: "%rbx", "%rax"
应该是:
: "rbx", "rax"
(哦,不要问我原因!)
编辑:您还需要使用-m64或类似编译64位 - 当然,假设您拥有的MingW编译器首先具有64位功能。
答案 1 :(得分:2)
MinGW是32位编译器。它不支持x86-64目标,因此您不能使用RAX之类的64位寄存器。至少这是在提出此问题之前发生的事情。我现在不确定mingw的情况,但是很长一段时间以来,它都不支持产生64位二进制文件。此外,它在很多方面都被破坏了,因为它使用了古老的MSVCRT运行时库,该库不支持标准C99 printf
格式说明符或80位long double
。开发人员也不愿更新或响应(拉出)请求,因此mingw-w64被派生了,它为Windows提供了更加完整的解决方案。它解决了所有printf
问题,为POSIX和Win32 API提供了更完整的支持,还有更多内容可供您稍后阅读
如果mingw的当前版本 支持x86-64,那么您仍然需要通过-m64
选项以使其输出64位可执行文件,因为在我查看their installer时,mingw仍然是32位编译器,并且默认情况下会编译为不存在RAX的32位代码。另请参见
但是更好的方法将是使用更好的编译器,例如mingw-w64,TDM-GCC或Clang,它们同时支持64位来宾和宿主
2005年,MinGW-w64由OneVision Software根据洁净室设计原则创建,因为原始的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的免费替代品)。