Tag: 对齐

x86_64对齐堆栈并在不保存寄存器的情况下恢复

我正在为x86_64编写中断处理例程。 ABI指定在调用C函数之前,我必须将堆栈对齐到16个字节。 x86_64 ISA指定在进入ISR时,我的堆栈是8字节对齐的。 我需要将我的堆栈指针对齐到16个字节。 问题是从我的C函数返回时,我必须恢复(可能)未对齐的堆栈指针,以便我可以正确地从我的中断返回。 我想知道是否有办法在不使用通用寄存器的情况下执行此操作?

在C中对齐printf()变量和小数

今天C的大问题。 所以我希望我的变量在列中对齐,同时是2位小数。 我知道要达到2位小数,我需要使用%.2f,如果我想要宽度,我使用%-30s。 但我无法将它们结合起来。 请参阅下面的代码,您将理解。 printf(“ItemA %.2f @ $3.34 $ %.2f\n”, huhu, totalhuhu); printf(“ItemB %.2f @ $44.50 $ %.2f\n”, haha, totalhaha); huhu,totalhuhu,haha,totalhaha都是浮点数。 我希望项目下的项目,价格在价格下对齐以及总数下的总数对齐是否1总数比另一个更多。 谢谢大家。

C – 可移植地获取类型对齐

我正在为一个非常简单的语言编写一个非常小的解释器,它允许简单的结构定义(由其他结构和简单类型组成,如int,char,float,double等)。 我希望字段尽可能少地使用字段,因此使用max_align_t或类似的东西是不可能的。 现在,我想知道是否有更好的方法来获得除此之外的任何单一类型的对齐: #include #include #define GA(type, name) struct GA_##name { char c; type d; }; \ const unsigned int alignment_for_##name = offsetof(struct GA_##name, d); GA(int, int); GA(short, short); GA(char, char); GA(float, float); GA(double, double); GA(char*, char_ptr); GA(void*, void_ptr); #define GP(type, name) printf(“alignment of “#name” is: %dn”, alignment_for_##name); int main() { GP(int, int); GP(short, short); […]

C 64位指针对齐

64位系统上的指针是否仍然是4字节对齐(类似于32位系统上的双精度)? 或者他们注意到8字节对齐? 例如,在64位系统上,以下数据结构有多大: struct a { void* ptr; char myChar; } 指针是否会被8字节对齐,导致7个字节的填充(字符总数= 8 + 8 = 16)? 或者指针是4字节对齐(4字节+4字节)导致3字节的填充(总= 4 + 4 + 4 = 12)? 谢谢,瑞恩

联盟规模大于预期。 如何在这里进行类型对齐?

#include union u1 { struct { int *i; } s1; struct { int i, j; } s2; }; union u2 { struct { int *i, j; } s1; struct { int i, j; } s2; }; int main(void) { printf(” size of int: %zu\n”, sizeof(int)); printf(“size of int pointer: %zu\n”, sizeof(int *)); printf(” size of […]

C编译器可以重新排列堆栈变量吗?

我曾经在嵌入式系统的项目上工作,我们重新安排了堆栈变量声明的顺序,以减少生成的可执行文件的大小。 例如,如果我们有: void func() { char c; int i; short s; … } 我们会将此重新排序为: void func() { int i; short s; char c; … } 由于对齐问题,第一个导致使用12个字节的堆栈空间,第二个导致仅8个字节。 这是C编译器的标准行为,还是我们使用的编译器的缺点? 在我看来,编译器应该能够重新排序堆栈变量,以便在需要时支持更小的可执行文件大小。 有人向我建议,C标准的某些方面可以防止这种情况,但我无法以任何方式找到信誉良好的来源。 作为一个额外的问题,这也适用于C ++编译器吗? 编辑 如果答案是肯定的,那么C / C ++编译器可以重新排列堆栈变量,你能给出一个肯定会这样做的编译器的例子吗? 我想看看编译器文档或类似的东西支持这一点。 再次编辑 谢谢大家的帮助。 对于文档,我能够找到的最好的东西是GCC (pdf)中的最佳堆栈槽分配 ,由Naveen Sharma和Sanjiv Kumar Gupta撰写,于2003年在海湾合作委员会峰会会议上提交。 这里讨论的项目是使用ADS编译器进行ARM开发。 在该编译器的文档中提到,像我所示的排序声明可以提高性能以及堆栈大小,因为ARM-Thumb架构如何计算本地堆栈帧中的地址。 该编译器没有自动重新排列本地人以利用这一点。 这里链接的文章说,截至2003年,GCC也没有重新安排堆栈帧以改善ARM-Thumb处理器的参考局部性,但它暗示你可以。 我找不到任何明确说明在GCC中实施的内容,但我认为这篇论文可以certificate你是正确的。 再次感谢。

对齐内存管理?

关于管理对齐的内存块,我有一些相关的问题。 跨平台的答案是理想的。 但是,由于我非常确定不存在跨平台解决方案,因此我主要对Windows和Linux以及(在很大程度上)Mac OS和FreeBSD感兴趣。 在16字节边界上对齐大块内存的最佳方法是什么? (我知道使用malloc()的简单方法,分配一些额外的空间,然后将指针碰到一个正确对齐的值。虽然我希望能找到一些不那么重要的东西。另外,请参阅以下是其他问题。) 如果我使用普通的旧malloc() ,分配额外的空间,然后将指针移动到正确对齐的位置,是否有必要将指针保持在块的开头以便释放? (在指向块中间的指针上调用free()似乎在Windows上实际运行,但我想知道标准是什么,即使标准说你不能,它是否在所有主要的实践中都有效操作系统。我不关心模糊的DS9K操作系统。) 这是一个艰难/有趣的部分 。 在保持对齐的同时重新分配内存块的最佳方法是什么? 理想情况下,这比调用malloc() ,复制,然后在旧块上调用free()更聪明。 我想尽可能在​​适当的地方做。

我们什么时候需要使用posix_memalign而不是malloc?

似乎posix_memalign允许您选择自定义alignment ,但何时需要? malloc已经在内部完成了对齐工作。 UPDATE 我问这个的确切原因是因为我看到nginx这样做, ngx_memalign(NGX_POOL_ALIGNMENT, size, log); ,这里NGX_POOL_ALIGNMENT被定义为16 , nginxs.googlecode.com/svn-history/trunk/src/core/ngx_palloc.c

现代处理器上的内存对齐?

我经常看到如下代码,例如,在内存中表示一个大位图: size_t width = 1280; size_t height = 800; size_t bytesPerPixel = 3; size_t bytewidth = ((width * bytesPerPixel) + 3) & ~3; /* Aligned to 4 bytes */ uint8_t *pixelData = malloc(bytewidth * height); (也就是说,一个位图被分配为一个连续的内存块,其字节bytewidth与一定数量的字节对齐,最常见的是4.) 然后通过以下方式给出图像上的一个点: pixelData + (bytewidth * y) + (bytesPerPixel * x) 这引出了两个问题: 对齐像这样的缓冲区会对现代处理器产生性能影响吗? 我应该担心对齐,还是编译器会处理这个问题? 如果它确实有影响,有人可以指向我找到各种处理器的理想字节对齐的资源吗? 谢谢。

联盟元素对齐

如果我有一个联合,C标准保证联合本身将与最大元素的大小对齐。 union U { long l; int i; short s; char c[2]; } u; 但它对联盟内各个联盟元素的对齐有什么看法呢? 以下表达式是否保证是真的? (&u.l == &u.i) && (&u.i == &u.s) && (&u.s == &u.c[0])