WebAssembly堆栈/堆栈指针初始化和内存布局

时间:2017-04-26 17:31:02

标签: webassembly

我目前正在使用通过LLVM编译的WebAssembly,但我还没有设法理解堆栈/堆栈指针以及它与整体内存布局的关系。

我了解到我必须使用s2wasm--allocate-stack N来运行我的程序,并且我认为这基本上是将(data (i32.const 4) "8\00\00\00")(N = 8)添加到我生成的wast中,二进制部分显然是指向内存偏移的指针,而i32常量是它在线性内存中的偏移量。

但是,我不太明白,为什么指针的值为56(同样N = 8)以及该值如何与内存中堆栈的确切区域相关联,在我的情况下,目前看起来像:

0-3: zero 4-7: 56 7-35: other data sections 36-55: zeroes 56-59: zero

我知道我可能更像是#34的候选人;只需使用emscripten",但我也想了解这一点。

  • 堆栈指针是否始终存储在线性存储器中的偏移量4处?
  • 如何计算其初始值? (与数据后的下一个偏移%16 == 0 + N对齐?)
  • 之前存储了什么,以及它指向的偏移后的内容是什么?

1 个答案:

答案 0 :(得分:4)

我在another question中谈到了这一点。从C ++的堆栈中,实际上有3个值可以结束的地方:

  1. 在执行堆栈上(每个操作码推送并弹出值,因此add弹出2然后按1)。
  2. 作为当地人。
  3. Memory
  4. 请注意,您不能使用1和2的地址。只有在这些情况下,我才会期望代码生成器与3一起使用。如何完成此操作不是由WebAssembly决定的,它&# 39;取决于你选择的任何ABI。 Emscripten和其他工具的作用是将堆栈指针存储在地址4,然后在程序的早期选择堆栈应该到达的位置。它不总是总是为4,但总是坚持ABI更简单,特别是如果涉及动态链接。

    在初始值上:该位置必须足够大以容纳整个堆栈,并且malloc的实现必须知道它,因为它不能在其上分配堆空间。这就是为什么某些工具允许您指定最大尺寸的原因。

    任何事物都可以存储在之前/之后(尽管你可能有先前的堆栈值)。 WebAssembly当前没有防护页面,因此耗尽内存堆栈会破坏堆值(除非代码生成器也发出堆栈检查)。这是所有"内存安全"因为它仍然无法逃脱WebAssembly.Memory,因此浏览器无法拥有,但开发人员自己的代码可以完全拥有。构建在WebAssembly之上的内存安全语言必须在WebAssembly.Memory内强制执行内存安全。

    请注意,我还没有解释1.和2.它们的存在意味着大多数C ++程序在WebAssembly中使用的内存中堆栈少于本机C ++程序使用堆栈。