【问题标题】:What is the relation to the order of which memory is stored与存储内存的顺序有什么关系
【发布时间】:2021-02-09 20:08:07
【问题描述】:

我一直在尝试并未能理解内存管理中的 [计算] 偏移量。

我想这样做的原因是因为我需要将一个数组传递给 WASM 来减去它,这是不可能的,因为 WASM 只有数字类型。 有人告诉我要实现这一点,我必须计算偏移量并通过 JavaScript 传入类型化数组。

我知道偏移量就是它们听起来的样子 - 从一个地址的位置到另一个地址的距离,但我不完全知道如何计算它。我找到的资源很好地解释了它是什么,但我一辈子都无法找出内存地址之间的关系来计算偏移量。

我不明白如何计算偏移量,因为我不完全知道内存存储的顺序(例如:内存是否以攀爬顺序存储,如 0x001、0x002、0x003)。

所以,要回答关于计算偏移量的问题,我必须首先回答主要问题 - 与存储内存的顺序有什么关系。

这一切都让我感到困惑,因为我来自一个高级语言环境,您通常不会使用偏移量和内存地址。

我曾经[试图]在这个问题上帮助我的资源:

【问题讨论】:

    标签: assembly memory webassembly


    【解决方案1】:

    在最简单的层面上,是的,内存就像一个巨大的数组,其元素是字节。
    (假设一个普通的现代计算机架构,一个字节可寻址而不是字,平面内存模型等)

    更广泛的访问可以一次加载多个字节,作为一个整数(或作为一个 FP double,如不在 TypedArray 中的 JavaScript 数字)。

    数组只是一个地址范围。 (或起始地址和长度,或起始地址和结束地址)。通过访问 start + offset 地址处的“内存”来使用数组的偏移量(在实际 CPU 程序集中),其中start 是数组第一个元素的地址。例如在 x86-64 汇编中,mov eax, [rdi + rsi*4] / ret 实现了 C 函数

    int32_t idx_arr(int32_t *array_start, size_t index) {
        return array_start[index];        // mov eax, [rdi + rsi*4]
    }
    

    请注意,在 asm 中,您必须手动按元素大小缩放索引以获得以字节为单位的偏移量。

    有趣的是,return *(array_start+index); 完全相同,因为 C 根据指针数学定义了 [] 运算符。通常你只需调用你的指针 arg array;我使用array_start 来说明,在汇编中,您通常只获得一个指向起点的指针,有时将长度或 end_ptr 作为单独的 arg,以便您可以循环遍历它。

    知道自己长度的数组对象或切片是高级构造,您可以使用包含 2 个指针的数据结构来实现。

    我不知道这在多大程度上适用于 Web 程序集,抱歉;在那里,您实际上可能会得到一个 TypedArray,它仍然可以进行边界检查以阻止您在数组边界之外写入或读取。在实际 CPU(或 C 语言)的 asm 中,如果您不根据已知长度手动检查 index,或者根据循环逻辑或您获得索引来自。

    【讨论】:

    • 嗯,我得再读一读。所以,偏移量以一种方式是以增加或减少大小来计算的,但我说的是多少。是每个内存地址+1,+2,等等?计算偏移量很容易,但如果不知道内存是如何存储的,我就无法做到。
    • @Reality:是的,内存的第一个字节地址为 0,下一个字节地址为 1,以此类推。 (在您的进程的虚拟地址空间内,通常您实际上不会映射地址 0。)但无论如何,相邻字节是 1 个地址相隔。 (这就是字节数组所暗示的)。相邻的 4 字节 int32 相隔 4 个地址,这就是在 x86 asm 中实现时将 C 索引缩放 4 = sizeof(int32_t) 的原因。 WASM 可能会为您进行缩放,我不知道,但如果是这样,那么您只需像在 JavaScript 中那样进行数组索引。
    • 啊,有道理。它还取决于字节的大小,这是有道理的(因为它存储字节)。好的,我仍然需要进行一些实验,但至少我对我正在做的事情了解更多。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 2015-11-22
    相关资源
    最近更新 更多