32 位系统中的 64 位可变读取顺序(低和高)

Posted

技术标签:

【中文标题】32 位系统中的 64 位可变读取顺序(低和高)【英文标题】:64 bit variable read order (low and high) in 32 bit systems 【发布时间】:2018-10-29 06:20:15 【问题描述】:

在 32 位系统中,当尝试读取 64 位变量时,会先读取哪些位?高的还是低的?或者也许它会有所不同,我们不能依赖它? 例如:

uint64_t counter = 4; uint64_t foo = counter;

所以当对 foo 的赋值发生时,计数器将以 2 个 32 位部分(低位和高位)读取,首先读取哪个部分?低或高,还是会有所不同?

【问题讨论】:

你在这里考虑什么语言?它看起来像 C/C++,但语言标签会有所帮助。 我不认为语言很重要,是的,它的 C/C++,我会编辑 C标准没有说,不同的硬件会做的不同。 您的问题似乎是 XY 问题。请参阅:What is the XY problem?uint64_t counter = 4; uint64_t foo = counter; 甚至没有提供高/低负载顺序差异的潜在示例。您正在尝试做的事情是什么会产生任何相关的影响? 好的,我明白了这个问题,但是如果您没有读取寄存器,因为它们在程序集中加载时填充,那么这有点深奥的问题。正如答案所提供的那样——这一切都取决于你的处理器是如何做到的。您可以在此之前将其分解并讨论首先通过数据总线的字节,但这完全取决于您的处理器指令集以及该硬件的负载情况。您的编译器必须以硬件使用的任何方式协调数据。 【参考方案1】:

据我所知,对于编译器如何实现此类操作没有任何规定。硬件也没有这样的规则。

试试这个

   #include <iostream>

    using std::cout;

    union _64test 
        uint64_t _64;
        uint32_t _32[2];
    ;

    int main() 

        _64test temp;
        temp._64 = 15;

        cout << temp._64 << "\n";
        cout << temp._32[0] <<" " << temp._32[1] << "\n";

        return 0;
    

输出:

15,

15 0


在我的情况下,低部分是第一。由于工会机制,你可以在任何你想要的地方解决这个问题


【讨论】:

这只是为了给我一个关于我的特定系统的答案,我想知道它对所有系统的影响。 @tomer.z 据我所知,对于编译器如何实现此类操作没有规定。 有些 CPU 是大端的。有些很小。无论哪种方式,所有代码都必须解决它。 问题不在于字节存储在内存中的逻辑顺序;这是关于内存访问的时间顺序。 啊-错过了。谢谢【参考方案2】:

所以当对 foo 的赋值发生时,计数器将以 2 个 32 位部分(低位和高位)读取,首先读取哪个部分?低或高,还是会有所不同?

可能会有所不同。

C 标准通常很少保证内存访问的顺序,尤其是对于未声明为volatile 的变量。甚至可能不会有两次内存访问,或者内存访问将被“拆分”(即,读取一半,执行其他操作,读取另一半)。

【讨论】:

所以基本上由每个处理器来决定,但是编程语言(在这个例子中是 C)可以强制执行命令,但在我们的例子中(C)它不可以吗? 编译器决定,而不是处理器。 它既是编译器,也不是处理器,而是架构。即使使用相同的编译器 (GCC),x86 和 ARM 也会以不同的方式处理这些情况。 @GRC 是的,我的意思是由编译器决定逐个案例。即使在特定的编译器/架构对上,它也可能不一致。 不,我没有混淆这两者。在 x86 32 位架构和 ARM 上键入 sizeof (long)。如果我没记错的话,一些 ARM 架构会将其截断为 32 位,而有些则有 2 个单独的 32 位内存块。

以上是关于32 位系统中的 64 位可变读取顺序(低和高)的主要内容,如果未能解决你的问题,请参考以下文章

Qt_32位程序在64位系统下读取64位注册表

Qt_32位程序在64位系统下读取64位注册表

软件152 高光顺

为啥我不能在 64 位机器上正确读取 HKCU 中的 32 位注册表值?

为什么一个指针在32位系统中占4个字节,在64位系统中占8个字节?

#yyds干货盘点# 面试官:说说32位和64位