标签: memory-alignment

在“C”中的结构元素之间手动插入填充字节

我有一组用于嵌入式应用程序(ARM 裸机)中的外设的 32 位寄存器,具有以下字节地址。

CTL 0x0;
STAT 0x4
TXR 0x8 <-- 不连续地址
RXR 0x20
DAT1 0x30 <-- 不连续地址
DAT2 0x40 <-- 不连续地址
等等

我想将所有这些寄存器分组到一个 C 结构中(它是一个打包结构)

struct my_peri {
     uint32_t CTL;
     uint32_t STAT;
     uint32_t TXR;
     uint32_t RXR;
     uint32_t DAT1;
     uint32_t DAT2;
};

struct my_peri* pPeri0 = (uint32_t*) (BASE_ADDRESS_OF_MY_PERI_0);
Run Code Online (Sandbox Code Playgroud)

现在如果我访问

pPeri->RXR;  // This will point to (BASE_ADDRESS + 0x10)
             // But the actual address i want to refer is (BASE_ADDRESS + 0x20)
Run Code Online (Sandbox Code Playgroud)

为了获得正确的地址,我在之间手动添加了一些元素

struct my_peri {
     uint32_t CTL;
     uint32_t STAT;
     uint32_t …
Run Code Online (Sandbox Code Playgroud)

c gcc struct bare-metal memory-alignment

2
推荐指数
1
解决办法
2761
查看次数

Linaro g++ aarch64编译导致未对齐错误

我使用 linaro g++ for ARM arch64 编译一个简单的 cpp 文件:

int main()
{
    char  *helloMain      = "main module (crm.c)";
    long  faculty, num    = 12;
    int   stop,mainLoop   = 1; 
    char  word[80]        = "";
}
Run Code Online (Sandbox Code Playgroud)

objdump生成elf文件后,我得到了它的asm代码:

0000000000001270 <main>:
int main()
{
    1270:   d101c3ff    sub sp, sp, #0x70
    char  *helloMain      = "main module (crm.c)";
    1274:   90000020    adrp    x0, 5000 <_malloc_trim_r+0x160>
    1278:   9111c000    add x0, x0, #0x470
    127c:   f90003e0    str x0, [sp]
    long  faculty, num    = 12;
    1280:   d2800180    movz    x0, #0xc
    1284:   f90007e0 …
Run Code Online (Sandbox Code Playgroud)

arm g++ memory-alignment arm64

2
推荐指数
1
解决办法
2804
查看次数

麻木错误?如何对齐 numpy 记录数组(“recarray”)?

更新:numpy 错误


不幸的是以下情况:

import numpy as np
a = np.zeros(4, dtype=np.dtype([('t', '<f8'), ('d', [('a', '<i4'), ('b', '<f8')], (100,))], align=True))
b = np.require(a, requirements=['ALIGNED'])
print([x.flags['ALIGNED'] for x in [a, b]])
Run Code Online (Sandbox Code Playgroud)

印刷[False, False]

我该如何对齐a

python numpy memory-alignment

2
推荐指数
1
解决办法
805
查看次数

汇编 - 堆对齐 - x86 intel

我想我理解堆栈对齐是4字节,例如,如果我只添加一个字符,他的地址将位于4字节的右侧(如果还有其他1或2字节变量,则稍早一点)

我仍然无法理解堆中的对齐方式,我认为有 4 字节或 8 字节对齐,但事情是这样的,当我分配 100 然后 20 字节时,第一个字节的末尾和开头之间有 4 个字节第二个,所以我猜测堆将使用 8 字节对齐。

通过连续分配 1 4 7 8 9 14 16 17 字节,我注意到 1、4、7、8、9 各占用 16 字节,14 16 17 各占用 24 字节,为什么呢?

我正在使用 C/C++ 并使用 malloc 进行分配(与 new 相同)。

谢谢。

malloc assembly heap-memory alignment memory-alignment

2
推荐指数
1
解决办法
1736
查看次数

为什么需要内存对齐?

我知道这个问题已经被问了一千次,我已经通读了每一个答案,但我仍然不明白。我的 RAM 模型可能存在一些基本错误,这使我无法理解任何答案。

我从互联网上获得了所有这些小信息,但我无法连接它们。

以下是我目前所知道的:以 IA-32 架构为例,其字边界为 32 位(边界 = CPU 可以从内存中读取的最大值?)。它将始终在其字边界内读取。

1)那么,无论我给它什么地址,它总是会读取 4 个字节?如果我在地址 x 有一个简单的字符怎么办。它会从那个地址读取 4 个字节,然后做一些奇怪的事情来只得到一个字节吗?

2)如果是这样,那么字符串(字符序列)n_chars * 4 字节大吗?我很确定它不是那样的,但是我应该如何解释“将始终阅读其单词边界”呢?

3)内存对齐似乎只与数据结构有关。为什么?内存的其余部分是否未对齐?我的意思是物理、虚拟、内核空间等?

4) 为什么我只能在可被 4 整除的地址中存储 32 位值?我的意思是我知道它最终只会读取 32 位,但为什么它不能从奇数地址读取 32 位?比如这里的限制是什么?

我只是很困惑请帮助我

memory x86 assembly memory-alignment low-level

2
推荐指数
1
解决办法
1839
查看次数

c++ 解决方案在 leetcode 上失败,地址未对齐错误,但在 Visual Studio 中运行

我是 C++ 新手,所以我正在尝试一些 leetcode 问题。我目前正在尝试最小堆栈问题。我想我已经正确解决了它,除了我从 leetcode 得到以下运行时错误:

Line 24: Char 37: runtime error: member access within misaligned address 0xbebebebebebebebe for type 'struct ListNode', which requires 8 byte alignment (solution.cpp)
Run Code Online (Sandbox Code Playgroud)

这是我的 Visual Studio 代码,带有测试 - 错误源自 push() 中的以下行:

                topStackNode->stackPrev = newNode;
Run Code Online (Sandbox Code Playgroud)

有谁知道什么会导致这种情况发生?我读了一点,一些有类似错误的人说这是因为 ListNode 没有初始化为 NULL,但我清楚地在我的结构中将所有 ListNode 初始化为 NULL。谢谢!

#include <vector>
#include <iostream>
using namespace std;
// design a stack that supports push, pop, top, and retrieving the minimum element in constant time


class MinStack {

struct ListNode {
    ListNode* stackNext;
    ListNode* …
Run Code Online (Sandbox Code Playgroud)

c++ pointers alignment memory-alignment

2
推荐指数
1
解决办法
1458
查看次数

结构与数组的对齐规则冲突

正如标题所暗示的,问题是关于Linux 上 x86-64 中聚合类型的对齐

在我们的讲座中,教授介绍了结构(及其元素)与附加幻灯片的对齐方式。因此,我会假设(根据维基百科和其他讲座材料)对于任何聚合类型,对齐是根据其最大成员。不幸的是,在以前的考试问题中似乎并非如此,它说:

“假设每个页表 [4kB,每个 PTE 64b] 都存储在内存中一个“自然对齐”的物理地址(即一个表大小的整数倍的地址),......”

为什么对于页表(它基本上是内存中的 8 字节值的数组),对齐规则不是根据最大的元素,而是根据整个表的大小?

非常感谢澄清!
菲利克斯 讲座幻灯片

x86 struct memory-alignment page-tables

2
推荐指数
1
解决办法
113
查看次数

处理器如何读取内存?

我正在尝试重新实现 malloc 并且我需要了解对齐的目的。据我了解,如果内存对齐,代码将执行得更快,因为处理器不必采取额外的步骤来恢复被切割的内存位。我想我明白 64 位处理器读取 64 位 x 64 位内存。现在,让我们假设我有一个按顺序排列的结构(没有填充):一个字符、一个短字符、一个字符和一个整数。为什么短路会错位?我们拥有区块中的所有数据!为什么它必须在一个 2 的倍数的地址上。对于整数和其他类型,同样的问题?

我还有第二个问题:使用我之前提到的结构,处理器如何知道当它读取它的 64 位时前 8 位对应于一个字符,然后接下来的 16 位对应于一个短等等......?

c cpu cpu-architecture memory-alignment low-level

2
推荐指数
1
解决办法
743
查看次数

为什么 C++17 引入了 std::aligned_alloc?

目的:了解 C++17 引入std::aligned_alloc动态内存管理的动机。

问题:对于 C++ 中的内存分配,std::malloc由于在什么情况下使用 malloc 和/或 new?. 相反,new在低级代码中几乎总是鼓励使用表达式(例如参见注释)。

尽管有这种气馁,我想知道为什么 C++17 引入了std::aligned_alloc它看起来像std::malloc.

C ++ 17(及更高版本)中是否有任何内容new(或其他鼓励使用的等效实用程序,如果有)无法执行?

尝试:我只能找到以下讨论,这仍然与我的问题有很大关系:

对齐 malloc 和标准 malloc 之间的区别?

c++ malloc memory-alignment c++17

2
推荐指数
1
解决办法
128
查看次数

为什么 movaps 会导致分段错误?

介绍

我试图让自己熟悉 AES 指令,然后使用能够更有意识地利用这些技术的库。然而,我不经常用汇编编程,所以我对这门语言有一些信心,但我不认为自己是专家。我已经编写了大约 150 条装配线的清单,以尝试使用英特尔提供的文档来使用这些功能。然而,我并没有成功地向前迈出许多步骤。

当我使用该指令时,由于 main 中的分段错误,程序崩溃了movaps。我已经尝试使用 gdb 和 valgrind 进行调试,但似乎一切正常,但事实并非如此。以下是导致问题的行。

代码

main:
start_f

    printstr

    movaps (string), %xmm15
==> movaps (key), %xmm0
    call   aes_encript

    movaps %xmm15, string
    printstr

end_f
Run Code Online (Sandbox Code Playgroud)

start_f并且end_f只是宏来启动和结束函数。我还提供了 .data 部分的代码,以显示应该没有问题:

    .data
string:
    .string "string"
    .fill   (128 - (.-string)), 1, 0

newline:
    .byte   0x0a

key:
    .fill   128, 1, 0

    .text
    .global _start
Run Code Online (Sandbox Code Playgroud)

调试信息

至于错误,无论是通过静态反汇编还是在gdb中,我都无法获得任何有用的信息。Valgrind 也没有帮助,这是意料之中的,因为我根本不接触堆。我展示了 gdb 中主要反汇编的部分清单:

   0x0000000000401022 <+0>:     push   %rbp
   0x0000000000401023 <+1>:     mov    %rsp,%rbp
   0x0000000000401026 <+4>:     mov    $0x402000,%rsi
   0x000000000040102d <+11>:    call …
Run Code Online (Sandbox Code Playgroud)

assembly sse memory-alignment segmentation-fault att

2
推荐指数
1
解决办法
126
查看次数