我目前正在使用通过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",但我也想了解这一点。
答案 0 :(得分:4)
我在another question中谈到了这一点。从C ++的堆栈中,实际上有3个值可以结束的地方:
add
弹出2然后按1)。Memory
。请注意,您不能使用1和2的地址。只有在这些情况下,我才会期望代码生成器与3一起使用。如何完成此操作不是由WebAssembly决定的,它&# 39;取决于你选择的任何ABI。 Emscripten和其他工具的作用是将堆栈指针存储在地址4
,然后在程序的早期选择堆栈应该到达的位置。它不总是总是为4,但总是坚持ABI更简单,特别是如果涉及动态链接。
在初始值上:该位置必须足够大以容纳整个堆栈,并且malloc
的实现必须知道它,因为它不能在其上分配堆空间。这就是为什么某些工具允许您指定最大尺寸的原因。
任何事物都可以存储在之前/之后(尽管你可能有先前的堆栈值)。 WebAssembly当前没有防护页面,因此耗尽内存堆栈会破坏堆值(除非代码生成器也发出堆栈检查)。这是所有"内存安全"因为它仍然无法逃脱WebAssembly.Memory
,因此浏览器无法拥有,但开发人员自己的代码可以完全拥有。构建在WebAssembly之上的内存安全语言必须在WebAssembly.Memory
内强制执行内存安全。
请注意,我还没有解释1.和2.它们的存在意味着大多数C ++程序在WebAssembly中使用的内存中堆栈少于本机C ++程序使用堆栈。