assembly - 与存储内存的顺序有什么关系
问题描述
我一直在尝试并且未能理解内存管理中的 [计算] 偏移量。
我想这样做的原因是因为我需要将一个数组传递给 WASM 来减去它,这是不可能的,因为 WASM 只有数字类型。有人告诉我要实现这一点,我必须计算偏移量并通过 JavaScript 传入类型化数组。
我知道偏移量就是它们听起来的样子 - 从一个地址的位置到另一个地址的距离,但我不完全知道如何计算它。我找到的资源很好地解释了它是什么,但我一辈子都无法找出内存地址之间的关系来计算偏移量。
我不明白如何计算偏移量,因为我不完全知道存储的内存顺序(例如:内存是否以爬升顺序存储,如 0x001、0x002、0x003)。
因此,要回答关于计算偏移量的问题,我必须首先回答主要问题——与存储内存的顺序有什么关系。
这一切都让我感到困惑,因为我来自一个高级语言环境,您通常不使用偏移量和内存地址。
我曾经[试图]在这个问题上帮助我的资源:
解决方案
是的,在最简单的层面上,内存就像一个巨大的数组,其元素是字节。
(假设一个普通的现代计算机架构,一个字节可寻址而不是字,平面内存模型等)
更广泛的访问可以一次加载多个字节,作为整数(或作为不在 TypedArray 中的 JavaScript 数字之类的 FP 双精度数)。
数组只是一个地址范围。(或起始地址和长度,或起始地址和结束地址)。通过在 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 Assembly,抱歉;在那里,您实际上可能会得到一个 TypedArray,它仍然可以进行边界检查以阻止您在数组边界之外写入或读取。在实际 CPU(或 C 语言)的 asm 中,如果您不手动检查index
已知长度,或者根据循环逻辑或您从中获取索引的已知内容证明它将在界限内,则没有什么能阻止这种情况。
推荐阅读
- mysql - 在mysql中搜索记录
- javascript - 为什么 HTML 画布中的对象在放大时不显示
- python - 在 Python 中通过动态分配将两个数组合并为一个
- java - spring mvc应用程序的linux服务器文件上传问题
- python - 制作自定义过滤器以迭代每个字段并检查返回的条件
- python-3.x - 在 chrome webdriver python selenium 上禁用控制台消息
- c++ - 从套接字接收一个大文件会淹没内存,我是否有内存泄漏?
- java - 硒中aShot和Shutterbug之间的区别
- linux - 在 nohup 内增加 while 循环会导致无限循环
- python - 如何从具有不同长度的子列表创建列表列表