与内存存储的顺序有什么关系
What is the relation to the order of which memory is stored
我一直在尝试并未能理解[计算]内存管理中的偏移量。
我之所以要这样做是因为我需要将一个数组传递给 WASM 来减去它,这是不可能的,因为 WASM 只有数字类型。
有人告诉我要实现这一点,我必须计算偏移量并通过 JavaScript.
传入类型化数组
我知道偏移量就像它们听起来的那样 - 从一个地址的位置到另一个地址的距离,但我不知道如何计算它。我找到的资源很好地解释了它是什么,但我无法找出内存地址之间的关系来计算偏移量。
我不明白offset是怎么计算的,因为我也不清楚内存的存储顺序(例如:内存是按照0x001、0x002、0x003这样的递增顺序存储的)
所以,要回答计算偏移量的问题,我必须先回答主要问题——内存存储的顺序有什么关系。
这让我很困惑,因为我来自高级语言环境,在这种环境中,您通常不会使用偏移量和内存地址。
我曾经[尝试]在这个问题上帮助我的资源:
在最简单的层面上,是的,内存就像一个巨大的数组,其元素是字节。
(假设一个普通的现代计算机体系结构,一个字节可寻址的非字、平面内存模型等)
更广泛的访问可以一次加载多个字节,作为整数(或作为 FP double,如 JavaScript 不在 TypedArray 中的数字)。
数组只是一个地址范围。 (或起始地址和长度,或起始地址和结束地址)。通过访问位于 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 作为一个单独的参数,所以你可以循环它。
知道自己长度的数组对象或切片是高级构造,您可以使用包含 2 个指针的数据结构来实现。
我不知道其中有多少适用于 Web 程序集,抱歉;在那里你实际上可能得到一个 TypedArray 仍然可以进行边界检查以阻止你在数组边界之外写入或读取。在真正的 CPUs(或 C 中)的 asm 中,如果您不根据已知长度手动检查 index
,或者根据循环逻辑证明它将在边界内,则没有什么可以阻止的,或者您从何处获取索引的已知内容。
我一直在尝试并未能理解[计算]内存管理中的偏移量。
我之所以要这样做是因为我需要将一个数组传递给 WASM 来减去它,这是不可能的,因为 WASM 只有数字类型。 有人告诉我要实现这一点,我必须计算偏移量并通过 JavaScript.
传入类型化数组我知道偏移量就像它们听起来的那样 - 从一个地址的位置到另一个地址的距离,但我不知道如何计算它。我找到的资源很好地解释了它是什么,但我无法找出内存地址之间的关系来计算偏移量。
我不明白offset是怎么计算的,因为我也不清楚内存的存储顺序(例如:内存是按照0x001、0x002、0x003这样的递增顺序存储的)
所以,要回答计算偏移量的问题,我必须先回答主要问题——内存存储的顺序有什么关系。
这让我很困惑,因为我来自高级语言环境,在这种环境中,您通常不会使用偏移量和内存地址。
我曾经[尝试]在这个问题上帮助我的资源:
在最简单的层面上,是的,内存就像一个巨大的数组,其元素是字节。
(假设一个普通的现代计算机体系结构,一个字节可寻址的非字、平面内存模型等)
更广泛的访问可以一次加载多个字节,作为整数(或作为 FP double,如 JavaScript 不在 TypedArray 中的数字)。
数组只是一个地址范围。 (或起始地址和长度,或起始地址和结束地址)。通过访问位于 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 作为一个单独的参数,所以你可以循环它。
知道自己长度的数组对象或切片是高级构造,您可以使用包含 2 个指针的数据结构来实现。
我不知道其中有多少适用于 Web 程序集,抱歉;在那里你实际上可能得到一个 TypedArray 仍然可以进行边界检查以阻止你在数组边界之外写入或读取。在真正的 CPUs(或 C 中)的 asm 中,如果您不根据已知长度手动检查 index
,或者根据循环逻辑证明它将在边界内,则没有什么可以阻止的,或者您从何处获取索引的已知内容。