2

为什么我们没有 4 位大小的数据类型?如果我们如此倾向于,为什么我们不能制造它们?我见过位域,但我听说它们不是可移植的,也许也不用?我认为这是机器如何解释位位置的位置值的结果。(大端,小端)

typedef struct
{
   int b1  : 1;
   int b2  : 1;
   ..
   ..
   ..
   int b32 : 1;
} bitfield32;

我们也不能像这样比任何原始类型都大的位域。那么为什么要限制呢?它可以在组装中完成吗?

4

2 回答 2

5

为什么我们没有 4 位大小的数据类型?

谁说的?Intel 4004 CPU有4 位寄存器和 4 位内存操作数。4 位数据类型对于这个 CPU 来说是很自然的,因为它们是直接支持的。

Intel 8051 CPU可以直接操作单个位的内存,因此您可以在其上使用 1 位变量。

这只是 CPU 的两个示例,其中数据类型可能非常小,比现在普遍存在的 8 位字节还小。

如果我们如此倾向于,为什么我们不能制造它们?

我们可以。您可以制作直接支持 4 位数据类型的 CPU,也可以将 4 位变量模拟为较大变量的一部分。

您可以将 2 个 4 位变量打包成一个 8 位字节。这种方法的问题是您需要使用更多指令从 8 位寄存器或内存位置中提取 4 位(AND为此您需要移位和掩码 ( ) 指令),同样您需要更多指令来正确保存 4-位值分成 8 位字节的一半(加载 8 位,清除 4 位一半中的旧值(使用 mask/ AND),移位新值,将其与其余部分组合并保存回来)。显然,这会对程序的代码大小及其速度产生负面影响。此外,4 位变量不是很有用,因为它们可以容纳的信息太少。由于这些原因,较小类型的模拟不是很流行。

我见过位域,但我听说它们不是可移植的,也许也不用?

它们被使用。它们的存在正是因为在某些(但不是全部)应用程序中它们非常有用。如果您有许多短变量,将其中的几个打包成一个字节或一个机器字可能是有利的,从而减少内存浪费。

它们并非完全不可移植。它们在 C 和 C++ 中的可移植性有限,因为语言标准没有精确定义较大数据类型中位域的位置和布局。这样做是为了让编译器编写者在处理位域时最有效地利用 CPU 功能。

6.7.2.1 Structure and union specifiers clause 101999 年的 C 标准中这样说:

实现可以分配任何大到足以容纳位域的可寻址存储单元。如果有足够的空间剩余,紧跟在结构中另一个位域之后的位域将被打包到同一单元的相邻位中。如果剩余空间不足,则将不适合的位域放入下一个单元还是与相邻单元重叠是实现定义的。单元内位域的分配顺序(高位到低位或低位到高位)是实现定义的。未指定可寻址存储单元的对齐方式。

 

我认为这是机器如何解释位位置的位置值的结果。(大端,小端)

是的,这是部分原因。但这绝不是专门针对位域的。常规的非位域类型也有这个问题。

我们也不能像这样比任何原始类型都大的位域。那么为什么要限制呢?它可以在组装中完成吗?

如果您的 C(或 C++)编译器(或解释器)可以模拟比 CPU 直接支持的类型更大的类型,那么您甚至可以拥有 256 位位域。

但同样,如果 CPU 直接支持的最大类型是 32 位,则意味着使用像 128 位这样的更大类型(无论是否位域)将导致更多代码和某些性能损失,因为单个CPU 指令(或其中的几个)将无法处理如此大的数据值。您将需要更多指令和更多时间来执行这些额外指令。

是的,这可以在组装中完成。只要您愿意编写代码并使其工作,任何事情都可以在汇编中完成。:)

于 2013-03-30T07:37:57.270 回答
3

为什么我们没有 4 位大小的数据类型?

因为像 x86 这样的现代处理器可以处理的最小数字是 8 位。

如果我们如此倾向于,为什么我们不能制造它们?

你可以,但它们会慢得多,因为你必须做比平常更多的工作,因为处理器不支持它。

它可以在组装中完成吗?

汇编对你的处理器来说只是一堆指令,所以只有你的处理器支持它,你才能有效地完成它。

如果您真正学习数字设计,那么其中很多都是有意义的。在那之前,您必须将这些限制视为理所当然。

于 2013-03-30T06:43:25.950 回答