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

时间:2015-02-12 20:33:42

标签: c assembly

我正在读一本关于集会的书,这里有一个我不太明白的陈述。它说访问最低有效位的最有效方法是使用以下代码:

*(unsigned char*)&a

有人可以向我解释为什么这么快吗?

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

2 个答案:

答案 0 :(得分:2)

也许你在抄写/解释这本书的内容时犯了错误。

首先,

*(unsigned char*)&a

无法访问。它访问一个字节。

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

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

答案 1 :(得分:2)

我会尝试解释。

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

  • 地址
  • 尺寸
  • 类型

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

所以,我们假设int的大小为4。

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

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

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位寄存器,则它可能比1读取快4个字节,因为读取一个实际上意味着2个操作:读取4,截断&扩大标志。