在SICP的第5.5.7节中,它说
External-entry
假设机器以val
启动,其中包含将结果放入val
并以(goto (reg continue))
结尾的指令序列的位置。
后面的部分说明了
为了将编译器生成的目标代码转换为评估程序寄存器机器的可执行指令,我们使用寄存器机器模拟器中的过程
assemble
(第5.2.2节)。然后,我们初始化val
寄存器以指向指令列表,设置flag
以便评估者转到external-entry
,然后启动评估器。
代码显示为:
external-entry
(perform (op initialize-stack))
(assign env (op get-global-environment))
(assign continue (label print-result))
(goto (reg val))
(define (compile-and-go expression)
(let ((instructions
(assemble (statements
(compile expression 'val 'return))
eceval)))
(set! the-global-environment (setup-environment))
(set-register-contents! eceval 'val instructions)
(set-register-contents! eceval 'flag true)
(start eceval)))
两段似乎都表明存储在'val
中的值是一个标签,指示在哪里跳转指令,但代码本身显示它们直接将寄存器的内容设置为指令序列。
此代码如何工作?当然他们没有将整个机器指令序列分配到一个寄存器中? (goto (reg val))
意味着'val
中存储的内容是一个标签,因此它不能是一系列指令,但这项指示意味着它不是。
供参考(所有代码均来自:https://mitpress.mit.edu/sicp/full-text/book/book-Z-H-4.html#%_toc_start):
(define (assemble controller-text machine)
(extract-labels controller-text
(lambda (insts labels)
(update-insts! insts labels machine)
insts)))
(define (extract-labels text receive)
(if (null? text)
(receive '() '())
(extract-labels (cdr text)
(lambda (insts labels)
(let ((next-inst (car text)))
(if (symbol? next-inst)
(receive insts
(cons (make-label-entry next-inst
insts)
labels))
(receive (cons (make-instruction next-inst)
insts)
labels)))))))
答案 0 :(得分:1)
请注意,SICP正在建模不是低级语言的寄存器机器,内存表示为单元格数组,地址表示为整数,但在Scheme中。
这意味着寄存器,指令等都是Scheme数据结构。
例如,一系列指令是一个列表,特别是一个交替标签和指令的列表,类似地,一个指针的“指针”只是一个变量,其值是一个指令列表(例如,参见关于Test, branch and goto instructions的部分,其中说:“goto指令类似于分支,但目的地可以指定为标签或寄存器”。