基本数据对齐问题

我一直在玩四周,看看我的电脑引擎盖下是如何工作的。 我很感兴趣的是看到的是一个函数内部堆栈上会发生什么。 要做到这一点,我写了下面的程序玩具:

#include <stdio.h> void __cdecl Test1(char a, unsigned long long b, char c) { char c1; unsigned long long b1; char a1; c1 = 'b'; b1 = 4; a1 = 'r'; printf("%d %d - %d - %d %d Total: %d\n", (long)&b1 - (long)&a1, (long)&c1 - (long)&b1, (long)&a - (long)&c1, (long)&b - (long)&a, (long)&c - (long)&b, (long)&c - (long)&a1 ); }; struct TestStruct { char a; unsigned long long b; char c; }; void __cdecl Test2(char a, unsigned long long b, char c) { TestStruct locals; locals.a = 'b'; locals.b = 4; locals.c = 'r'; printf("%d %d - %d - %d %d Total: %d\n", (long)&locals.b - (long)&locals.a, (long)&locals.c - (long)&locals.b, (long)&a - (long)&locals.c, (long)&b - (long)&a, (long)&c - (long)&b, (long)&c - (long)&locals.a ); }; int main() { Test1('f', 0, 'o'); Test2('f', 0, 'o'); return 0; }

而这个吐出如下:

9月19日至13日 - 4个8共计:53

八月八日至24日 - 4个8共计:52

该函数参数都表现良好,但由于指定的调用约定,我期望这一点。 但局部变量都有点靠不住。 我的问题是,为什么不这是一样的吗? 第二呼叫似乎产生更紧凑的和更好的对准的堆栈。

纵观ASM是unenlightening(至少对我来说),因为变量地址仍然有别名。 所以我想这的确是一个关于自身分配栈局部变量汇编问题。

我认识到,任何具体的答案很可能是特定于平台的。 我更感兴趣的是一个一般性解释,除非这个怪癖真的是特定的平台。 因为虽然记录在案,我与64位英特尔机器上编译VS2010。

--------------解决方案-------------

POD结构的内存布局是相当多指定和语言规则你的平台上+对齐类型/大小要求保证。

实现了免提与局部变量和函数参数。 这是最有可能的,它使得其中的一些在堆栈只是因为你使用一元和运营商把他们的地址。

当不使用则局部变量的编译器可以优化其初始化。 当局部简单变量的使用非常密集那么编译器可能会使用注册它。 当本地变量只使用一次,然后编译器可以代替使用的直接使用它的值。

如果你想功能参数布局得到更好的指定/保证,那么你必须使用extern“C”链接。

在测试1,定义了一堆局部变量。 编译器不强制打包在一起,或以相同的顺序,你声明它们。

在Test2的,你定义一个结构,编译器垫使用的数据http://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86

分类:C# 时间:2015-03-15 人气:0
本文关键词: C#,VISUAL C ++,低水平
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.869 (s). 10 q(s)