为什么本地类型总是得到一个偶数地址?

为什么本地类型总是得到一个偶数地址?

为什么地址的顺序与代码中的变量不一样呢?

保证结构中的第一个元素位于与结构本身相同的位置(如果它们是某个元素的成员),但其他元素不能保证按任何顺序排列。通常,编译器会对它们进行适当的排序,以允许它使用最少的空间。对于局部变量,它们位于内存中的位置完全取决于编译器。它们可能都位于同一个区域(可能是因为它利用了本地的优势),或者它们可能都在地图上(如果您有一个糟糕的编译器)。

每个地址都是偶数?

它把它们放在词的边界上。这使得内存访问比没有放在字边界上的内存更快。例如,如果将a放在一个单词的最后一个字节上,另一个单词的第一个字节上:

代码语言:javascript复制| WORD 1 | WORD 2 |

|--------|--------|--------|--------|--------|--------|--------|--------|

| a[0] | a[1] |然后访问a[0],然后访问a[1],将需要将2个单词加载到缓存中(每个缓存丢失)。沿着一个词的边界:

代码语言:javascript复制| WORD 1 |

|--------|--------|--------|--------|

| a[0] | a[1] |a[0]上的缓存丢失将导致同时加载a[0]和a[1] (减少不必要的内存带宽)。这利用了局部性原则。虽然语言当然不需要它,但它是编译器所做的一种非常常见的优化(除非您使用预处理器指令来阻止它)。

在您的示例中(按其顺序显示):

代码语言:javascript复制3734044 b[0]

3734045 b[1]

3734046 b[2]

3734047 -----

3734048 a[0]

3734049 a[1]

3734050 -----

3734051 -----

3734052 arg

3734053 -----

3734054 -----

3734055 -----

3734056 f[0]

3734057 f[1]

3734058 f[2]

3734059 f[3]

3734060 f[4]

3734061 f[5]

3734062 f[6]

3734063 f[7]

3734064 f[8]

3734065 f[9]

3734066 f[10]

3734067 f[11]

3734068 f[12]

3734069 -----

3734070 -----

3734071 -----

3734072 e[0]

3734073 e[1]

3734074 e[2]

3734075 e[3]

3734076 e[4]

3734077 e[5]

3734078 e[6]

3734079 e[7]

3734080 c[0]

3734081 c[1]

3734082 c[2]

3734083 c[3]

3734084 c[4]

3734085 c[5]

3734086 -----

3734087 -----

3734088 d[0]

3734089 d[1]

3734090 d[2]

3734091 d[3]

3734092 d[4]假设没有为这些漏洞分配其他数据,那么无论您在编译器中拥有什么设置,都会确保您的所有数组都从一个word边界开始。这并不是说它在数组之间添加空间(正如您所看到的,e和c之间没有空格),而是第一个元素必须位于单词边界上。这是具体的实现,而不是标准所要求的。

相关数据