【问题标题】:GCC quad size 32 and 64 bitGCC Quad 大小 32 和 64 位
【发布时间】:2013-10-15 10:16:20
【问题描述】:

我在 Linux 上使用 GCC 编译器。
我想使用 64 位编译器并使用 -m32 选项(32 位兼容性)构建我的一些文件。我发现编译器的奇怪(对我而言)行为。
我的代码很简单:

int main () {
   int test =(((0) & 0x00000000) << (32));
   return 0;
}

对于这段代码,我收到了 326464 以及 -m32 编译器的警告:

warning: left shift count >= width of type [enabled by default]

但是当我试图从assebmly code 编译它时:

.quad (((0) & (0x00000000)) << (32))

我收到了仅针对 32 bit 编译器的警告:

Warning: shift count out of range (32 is not between 0 and 31)

为什么从casm 文件编译的相同代码对于不同编译器(32 位和 64 位)的警告不同?

编辑:

我在哪里可以找到.quad 的定义,我的意思是在代码中?

【问题讨论】:

  • 嗯,一个来自 C 编译器,另一个来自汇编器,似乎没有必要让错误完全相同,只要它们包含相同的信息。顺便提一句。为什么这被标记为 C++?
  • @PlasmaHH 呃,抱歉我不想在标签中添加c++...

标签: c gcc assembly compilation


【解决方案1】:

在 64 位模式下,gcc 使用 LP64 约定。这意味着 long 和指针是 64 位宽,但 int 仍然只有 32 位宽。在表达式中

  int test =(((0) & 0x00000000) << (32));

所有常量都假定为ints,因为int 大到足以容纳所有常量,而ints 始终只有32 位。类型的 shift >= width 的结果是 C 中的 UB,因为行为通常取决于底层架构的 shift 指令。

通过强制其中一个数字为 64 位来抑制警告。

long test =(((0) & 0x00000000L) << (32)); // Still gives a warning with -m32

long long test =(((0) & 0x00000000LL) << (32)); // No warning, long long is always 64 bit

【讨论】:

  • 感谢您的完整回答。但是为什么我在编译 asm 代码时结果(警告)不同呢?
  • 还有如何将LL 添加到宏定义或asm 文件中?
【解决方案2】:

在 C 语言中,左移操作数的类型是 int,在两个平台上都是 32 位的,因此对于 C 语言而言,移位始终是未定义的行为。

我想在您的汇编程序中,操作数分别是 32 位或 64 位。

【讨论】:

  • 事实上他正在使用.quad,这样即使在32位模式下也可以使用64位。如果汇编器产生警告,那就是错误或限制。
猜你喜欢
  • 2013-01-11
  • 1970-01-01
  • 2011-02-05
  • 1970-01-01
  • 1970-01-01
  • 2013-10-23
  • 2011-01-28
  • 2010-12-01
  • 1970-01-01
相关资源
最近更新 更多