为什么 Forth 为每个变量保留两个单元格?
Why does Forth reserve two cells per variable?
在试图找出 Forth 如何管理字典(以及一般的内存)时,我遇到了 this page. Being familiar with C, I have no problem with the concept of pointers, and I assume I understood everything correctly. However, at the end of the page are several exercises,在这里我注意到了一些奇怪的事情。
习题 9.4,假设 DATE
被定义为 VARIABLE
,问
之间有什么区别
DATE .
和
' DATE .
和练习9.5使用用户变量BASE
.
做同样的事情
根据提供的答案,两个短语将给出相同的结果(BASE
)。然而,用 Win32Forth 尝试这个,给出的结果相差 4 个字节(1 个单元格)。这是我所做的:
here . 4494668 ok
variable x ok
x . 4494672 ok
' x . 4494668 ok
创建另一个变量会得到类似的结果:
variable y ok
y . 4494680 ok
' y . 4494676 ok
因此,看起来每个变量得到的不仅仅是一个单元格(用于值),而是两个单元格。变量本身指向存储实际值的位置,并在执行令牌处检索内容(使用 ' x ?
)为两个变量提供 0040101F
。
对于 练习 9.5,我的结果是:
base . 195F90 ok
' base . 40B418 ok
这些甚至彼此都不近。但是,此练习的答案确实提到结果可能取决于 BASE
的定义方式。
回到普通变量,我的主要问题是:为什么每个变量保留两个单元格?
此外:
- 由于只有一个单元格包含实际值,那么另一个单元格的内容是什么意思?
- 这是 Win32Forth 特有的吗?在其他实现中会发生什么?
- run-time 和 compile-time 变量是否不同?
- 如何将上述问题的答案应用于用户变量(例如
BASE
)?
EDIT1: 好吧,Forth 还为每个变量存储了一个 header,使用 '
可以得到这个 [=75] 的地址=].根据我的测试,我会得出结论 header 只使用一个单元格,这并不对应于 header 应该包含的所有信息。其次,根据练习,检索变量的地址对于这两种情况应该给出相同的结果,这似乎与 header 的存在完全矛盾。
我的直觉是这一切都非常implementation-specific。如果是这样,在 Win32Forth 中会发生什么,根据练习应该会发生什么?
这就是使用传统内存布局在字典中定义的大致样子。请注意,实现可能与此有很大差异,有时会有很大差异。特别是,字段的顺序可能不同。
Link to previous word (one cell)
Flags (a few bits)
Name length (one byte, less a few bits)
Name string (variable)
Code field (one cell)
Parameter field (variable)
除了代码和参数字段之外的所有内容都被视为 header。代码字段通常在参数字段之前。
用 '
勾选一个词会给你一个 XT,或执行令牌。这可以是实现喜欢的任何内容,但在许多情况下,它是代码字段的地址。
执行一个用CREATE
或VARIABLE
创建的词给你参数字段的地址。
这可能就是为什么在 Win32Forth 中,两个地址相差 4 个字节,或一个单元格。我不知道为什么练习题的答案应该没有区别。
假设BASE
是一个用户变量,它大概是这样工作的:每个任务都有自己的用户区,用户变量被分配在其中。所有用户变量都知道它们在该区域内的特定偏移量。勾选 BASE
给你它的 XT,它对所有任务都是一样的。执行 BASE
通过将其偏移量添加到用户区域的基址来计算地址。
在试图找出 Forth 如何管理字典(以及一般的内存)时,我遇到了 this page. Being familiar with C, I have no problem with the concept of pointers, and I assume I understood everything correctly. However, at the end of the page are several exercises,在这里我注意到了一些奇怪的事情。
习题 9.4,假设 DATE
被定义为 VARIABLE
,问
DATE .
和
' DATE .
和练习9.5使用用户变量BASE
.
根据提供的答案,两个短语将给出相同的结果(BASE
)。然而,用 Win32Forth 尝试这个,给出的结果相差 4 个字节(1 个单元格)。这是我所做的:
here . 4494668 ok
variable x ok
x . 4494672 ok
' x . 4494668 ok
创建另一个变量会得到类似的结果:
variable y ok
y . 4494680 ok
' y . 4494676 ok
因此,看起来每个变量得到的不仅仅是一个单元格(用于值),而是两个单元格。变量本身指向存储实际值的位置,并在执行令牌处检索内容(使用 ' x ?
)为两个变量提供 0040101F
。
对于 练习 9.5,我的结果是:
base . 195F90 ok
' base . 40B418 ok
这些甚至彼此都不近。但是,此练习的答案确实提到结果可能取决于 BASE
的定义方式。
回到普通变量,我的主要问题是:为什么每个变量保留两个单元格?
此外:
- 由于只有一个单元格包含实际值,那么另一个单元格的内容是什么意思?
- 这是 Win32Forth 特有的吗?在其他实现中会发生什么?
- run-time 和 compile-time 变量是否不同?
- 如何将上述问题的答案应用于用户变量(例如
BASE
)?
EDIT1: 好吧,Forth 还为每个变量存储了一个 header,使用 '
可以得到这个 [=75] 的地址=].根据我的测试,我会得出结论 header 只使用一个单元格,这并不对应于 header 应该包含的所有信息。其次,根据练习,检索变量的地址对于这两种情况应该给出相同的结果,这似乎与 header 的存在完全矛盾。
我的直觉是这一切都非常implementation-specific。如果是这样,在 Win32Forth 中会发生什么,根据练习应该会发生什么?
这就是使用传统内存布局在字典中定义的大致样子。请注意,实现可能与此有很大差异,有时会有很大差异。特别是,字段的顺序可能不同。
Link to previous word (one cell)
Flags (a few bits)
Name length (one byte, less a few bits)
Name string (variable)
Code field (one cell)
Parameter field (variable)
除了代码和参数字段之外的所有内容都被视为 header。代码字段通常在参数字段之前。
用 '
勾选一个词会给你一个 XT,或执行令牌。这可以是实现喜欢的任何内容,但在许多情况下,它是代码字段的地址。
执行一个用CREATE
或VARIABLE
创建的词给你参数字段的地址。
这可能就是为什么在 Win32Forth 中,两个地址相差 4 个字节,或一个单元格。我不知道为什么练习题的答案应该没有区别。
假设BASE
是一个用户变量,它大概是这样工作的:每个任务都有自己的用户区,用户变量被分配在其中。所有用户变量都知道它们在该区域内的特定偏移量。勾选 BASE
给你它的 XT,它对所有任务都是一样的。执行 BASE
通过将其偏移量添加到用户区域的基址来计算地址。