javascript - 如何使用 1 个全局内存数组在 JavaScript 中模拟带有参数和局部变量的调用堆栈?
问题描述
我已经坚持了几天。基本上我可以把它总结为问,你如何模拟这个函数,就像它是用汇编编写的(或者甚至是机器代码,只使用 1 个内存数组的东西),但是用 JavaScript 做所有事情?
function start() {
let x = doX(1, 2)
let y = doX(3, 4)
let z = doX(x, y)
return z
}
function doX(a, b) {
let x = a + b
let y = a - b
let z = x * y
return z
}
所以我的尝试是这样的:
const memory = []
function start() {
// capture push (function prologue)?
memory[0] = 1
memory[1] = 2
doX()
memory[2] = memory[100]
memory[0] = 3
memory[1] = 4
doX()
memory[0] = memory[2]
memory[1] = memory[100]
doX()
// capture pop (function epilogue)?
memory[100] = memory[100]
}
function doX() {
// somehow allocate space "on the stack"
// using only this memory object?
// don't know how to do that....
memory[10] = memory[0] + memory[1]
memory[11] = memory[0] - memory[1]
memory[12] = memory[10] * memory[11]
// put it on the return register?
memory[100] = memory[12]
}
如何仅使用此内存数组正确添加推送和弹出操作并使其看起来正确?另外,我对所有内存地址进行了硬编码,如何正确地使它们相对?
解决方案
您需要一个堆栈指针,或者作为一个单独的全局变量(例如具有与内存分开的寄存器的 CPU),或者只是为这个特殊用途选择一个内存位置。就像@bergi在回答您之前的问题时所解释的那样,您需要做一些事情,比如memory[tos++]
将东西推送到堆栈上,而不是假设堆栈指针的起始值是0
通过硬编码存储到memory[0]
.
(在包括 x86 在内的许多 ISA 中,堆栈指针从区域中的最高地址开始,将堆栈中的内容压入堆栈会从堆栈指针中减去。因此它会向下增长)。
您已经将memory[100]
其用作返回值寄存器,而不是让 JavaScript 返回值。 如果memory[99]
需要,可以用作堆栈指针,因此您可能有类似mem[ --mem[99] ] = val_to_push
. sp
如果您使用可以调用的单独变量,或者state.sp
如果您想定义一个带有内存和一些标量寄存器(包括sp
堆栈指针)的状态对象,那么它显然更具可读性。
真正的调用约定在寄存器中返回,而不是在内存中;使用“在内存中”的 retval 寄存器是不必要的复杂化。如果你让 JS 函数通过 JS 机制返回值,它仍然类似于 CPU,并认为它是一个寄存器。只要您将其限制为简单的数字。
既然你要弥补你的机器的细节,你可以使用 JS 局部变量作为临时寄存器,并允许函数有尽可能多的。
因此,为这台机器编程有点像 LLVM-IR,您只需使用任意数量的“寄存器”,LLVM 负责实际存储它们的位置。但不是真的;您的代码不会“编译”以将多余的寄存器溢出到堆栈中,它确实具有您想要使用的尽可能多的寄存器。
要将它们视为寄存器并且不让它退化为不使用的纯 JS memory[]
,您仍然可以要求通过内存进行 arg传递(即堆栈参数调用约定),并假装函数调用破坏了所有的值局部变量。
推荐阅读
- javascript - 创建步行循环动画Javascript/CSS
- php - 如何正确使用 Scandir()?
- sql - SQL - 在别名上按 Max() 排序
- reactjs - 如何将 react-i18next 与连接的组件一起使用
- swift - 旋转 CollectionViewCell 后计算单元格偏移量
- bash - 计划在午夜运行的 BASH 脚本 cron - 每分钟运行一次,直到凌晨 12:20
- socket.io - 如何从java向socket io服务器发送消息
- java - 我无法从 java 运行 python 脚本,我认为这是因为脚本没有执行权限
- c++ - 如何将数据写入标准输入以供等待标准输入输入的单独线程使用?
- excel - 字符串在 InsertFile 中有效。包含相同字符串的变量不会。为什么?