c-访问整数最低有效位的最快方法



我正在读一本关于汇编的书,这里有一句我不太理解的话。它说,访问最低有效位的最有效方法是使用以下代码:

*(unsigned char*)&a

有人能解释一下为什么这么快吗?

有人告诉我,我需要很好地理解组装才能得到这个。

我会尽力解释。

每当变量存储在内存中时,它都有几个重要的属性:

  • 地址
  • 尺寸
  • 类型

从你的问题中,我怀疑你问的是大于1的整数变量。例如,int类型由C标准定义为fastat least 16 bit。这使得它为2到4个字节。

假设int的大小为4。

然后我们知道,变量占用了四个字节,其中有一些起始地址(&a):addr+0、addr+1、addr+2、addr+3。

当谈到C约定时,您可以将指针从一种类型转换为另一种类型,并使用它来访问数据(假设您知道自己在做什么)。在我们的例子中,我们知道char只有1个字节长。因此,我们可以使用直接存储器访问从单个int中提取4个char

char ch0 = *((char *)&a + 0); // OR ((char*)&a)[0]
char ch1 = *((char *)&a + 1); // OR ((char*)&a)[1]
char ch2 = *((char *)&a + 2); // OR ((char*)&a)[2]
char ch3 = *((char *)&a + 3); // OR ((char*)&a)[3]

现在我们有4个字节,问题是:哪个字节包含哪些值。也就是说,当我们的a等于0x12345678时,我们可能有多种替代方法,即不同部分在存储器中的排序方式。

在x86上(这与您的情况非常接近),顺序是这样的,所以首先存储我们的int(0x78)的最低部分,然后存储第二部分,依此类推:

a              : 0x12345678
((char*)&a)[0] : 0x78
((char*)&a)[1] : 0x56
((char*)&a)[2] : 0x34
((char*)&a)[3] : 0x12

所以,要访问最低有效位,我们需要从最低有效字节访问最低有效比特。获胜者是*(char*)&a。但是比特值是:

*(char*)&a & 1

现在,关于为什么它不完全正确。即使在x86上。与我们谈论的真正的8位处理器不同,许多处理器的设计经过优化,可以在与寄存器大小匹配时以最快的方式访问对齐的数据。所以,若处理器有32位寄存器,它读取4个字节的速度可能比读取1快,因为读取一个字节实际上意味着两个操作:读取4、截断&展开符号。

也许你在转录/转述这本书的内容时出错了。

首先,

*(unsigned char*)&a

一点也不访问。它访问一个字节。

其次,不一定是意义最小的字节。它是小端序系统中最不重要的字节。在大端序系统中,它是最重要的字节。

在任何一种情况下,它都访问整数的最低寻址字节。

最新更新