body, table{font-family: 微软雅黑}
table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;}
th{border: 1px solid gray; padding: 4px; background-color: #DDD;}
td{border: 1px solid gray; padding: 4px;}
tr:nth-child(2n){background-color: #f8f8f8;}

FORTH 系统的内存分布图又可以分为单用户FORTH和多用户poly FORTH 那样的多道程序系统。最简单的就是单用户的FORTH系统:

预编译系统(precompiled  portion)

    在内存低区驻留着系统唯一的预编译部分(已经被编译成词典形式)。在一些系统中,这种代码被保存在磁盘上(通常在1~8块中),当你启动或“引导”计算机时,他被自动装配进RAM低区。在另一些系统中,预编译部分永久驻留在PROM中,只要你一启动计算机它便可以被使用。
    预编译部分通常包括大部分单字长算术运算符和数字格式化词,单字长栈操作符,编辑命令,转移和结构控制词,汇编程序,差不多笔记做到现在遇到过的定义词。也包括文本和地址解释程序。

系统变量(System Variables)
    这个区域包含有预编译部分生成的并可由整个系统使用的“系统变量”。他们一般情况下是不能被用户使用的。

任选定义(Elective Definitions)
    未被预编译的FORTH系统部分以源文本形式保存在磁盘上。这是为了更好的控制使用内存空间,可以根据需要决定装配还是不装配这些定义中的任何部分。所有“任选定义”的装配块称为“任选快”。比如16块,16 LOAD   可以加载一个小屏面编辑程序。

用户词典(User Dictionary)
    在内存中能存贮自己定义的词的区域称为“用户词典”,词典区随着新词的增加向内存高区生成。词典中下一个可以用单元总是由变量 DP 指示。在编译过程中,随着词典条目的增加,指针 DP 也逐单元(或逐字节)地调整。因此,DP 是编译程序的书签;在词典中指向的位置是编译程序下次可编译的地方。
    DP 可能被 ALLOT 使用。ALLOT 使DP向前推进给定数量的字节数。系统中有一个词 HERE 就是用DP实现的 。
DP (  ---  addr  )    词典指针变量,它包含词典中下一个自由存储地址,他的值可以由HERE给出,也可以由ALLOT更改。
HERE   (   ---  addr  )   把下一个可用词典位置的地址留在堆栈顶;(定义里面就用到了上面的指针变量 DP)

高速暂存缓冲区(The Pad)
    词典中HERE一固定距离有一个小块叫做“高速暂存缓冲区”它通常用于保存先被操作然后送往终端的 ASCII 码字符串。例如,在使用 TYPE 之前,数字格式化词用这个区域来保存转换过程中的数字的 ASCII 码。
    pad的大小没有限制。在大多数系统中,在pad的起点到参数堆栈栈顶之间有数百个甚至数千个字节。
    由于pad的起始地址被规定与最后的词典条目有关,所以每当加入新的定义或执行了 FORGET 或 EMPTY 之后,该起始地址都会发生变化。但是这种安排是安全的。因为当上述时间中的任何一件发生时,pad都不会被用到。词 PAD 给出了pad的当前起始地址。
 //可以看出pad的空间大小是256 (0-255)刚好是一个字节。
PAD  (  ---   addr  )    留下保存中间处理过程数据的暂存区低地址。PAD的地址或内容可以改变,如果下一个可用词典单元的地址被改变,则这些数据被舍弃。PAD的容量为84个字符。

参数堆栈(Parameter Stack)
    数据压入数据堆栈的时候只是栈顶指针的移动;把一个数放入堆栈是,指针先减1,然后数值被存入指针指向的位置。一个数移出堆栈,指针增加1。(堆栈地址是从低到高,数据最先存在在地址高位上,向上增长也是就向着低地址方向增长)。数据堆栈是向下生长(向着地址减小的方向增长)
SP@   (  ---  addr  )   将堆栈顶地址回送到堆栈顶的与计算机相关过程,所说的堆栈顶的地址是指在执行SP@之前的地址。(取出堆栈顶指针)
有了这个就可以随心所欲的访问堆栈中任意位置的元素。(最好不要在编程中使用)
S0  (  ---  addr  )    含有“堆栈指针初始值的用户变量。
SP@  (  ---  addr  )  将堆栈顶地址回送到堆栈顶的与计算机相关过程,所说的堆栈顶的地址是指在执行SP@之前的地址。
栈底由一个 S0 的变量指示。S0 的内容总是“空栈”单元的下一个单元的地址。

输入信息缓冲区(Input Message Buffer)
    S0 也包含着“输入信息缓冲区”的起始地址。输入信息缓冲区向内存高区生成(与pad方向相同)。当从终端输入文本时,文本便存放在此缓冲区,文本解释程序将在此缓冲区内扫描文本。

返回堆栈(Return Stack)
    在输入信息缓冲区的上面是返回堆栈,其操作相同于参数堆栈,但是返回堆栈没有类似于SP@和S0这样的高级FORTH词。

用户变量区(User Variables)
    返回堆栈上面就是用于存放“用户变量”的内存区域,这些变量包括 BASE ,S0 ……

块缓冲区(Block Buffers)
    在高端内存区是若干块缓冲区。每个缓冲区为一个磁盘块提供1024个字节空间。当访问磁盘快的时候(显示或装配),系统将该块从磁盘中复制到缓冲区,在缓冲区能由编辑程序修改该块或由 LOAD 解释该块。

Forth 内存布局的更多相关文章

  1. 图说C++对象模型:对象内存布局详解

    0.前言 文章较长,而且内容相对来说比较枯燥,希望对C++对象的内存布局.虚表指针.虚基类指针等有深入了解的朋友可以慢慢看. 本文的结论都在VS2013上得到验证.不同的编译器在内存布局的细节上可能有 ...

  2. C++ 系列:内存布局

    转载自http://www.cnblogs.com/skynet/archive/2011/03/07/1975479.html 为什么需要知道C/C++的内存布局和在哪可以可以找到想要的数据?知道内 ...

  3. C++类内存布局图(成员函数和成员变量分开讨论)

    一.成员函数 成员函数可以被看作是类作用域的全局函数,不在对象分配的空间里,只有虚函数才会在类对象里有一个指针,存放虚函数的地址等相关信息. 成员函数的地址,编译期就已确定,并静态绑定或动态的绑定在对 ...

  4. 根据内存布局定位的一个fastdfs坑

    在使用fastdfs时,编写数据上传代码时,遇到一个坑.最终根据指针对应的内存布局定位到一个其client API的一个坑,值得记录一下.具体是在 tracker_connect_server() 这 ...

  5. c++ 对象的内存布局

    之前介绍过了普通对象比如系统自带的int等对象的对齐方式,在学习类型转换的时候遇到了自定义类型的继承体系中的downcast与upcast. 于是顺藤摸瓜,摸到了这里.发现还是 陈皓的博客里面写的最早 ...

  6. C++使用继承时子对象的内存布局

    C++使用继承时子对象的内存布局 // */ // ]]>   C++使用继承时子对象的内存布局 Table of Contents 1 示例程序 2 对象的内存布局 1 示例程序 class ...

  7. .NET对象的内存布局

    每个虚拟机都有它自己的对象布局,本文我们将针对sscli源码和windbg调试器来查看不同类型的.net对象布局. 在.net虚拟机里,每个对象都需要保存这些信息: 对象的类型: 对象实例的成员属性( ...

  8. c/c++ 对象内存布局

    一.对象内存查看工具 VS 编译器 CL 的一个编译选项可以查看 C++ 类的内存布局,非常有用.使用如下,从开始程序菜单找到 Visual Stdio 2012. 选择 VS 的命令行工具,按如下格 ...

  9. C++ Data Member内存布局

    如果一个类只定义了类名,没定义任何方法和字段,如class A{};那么class A的每个实例占用1个字节的内存,编译器会会在这个其实例中安插一个char,以保证每个A实例在内存中有唯一的地址,如A ...

  10. C++中派生类对象的内存布局

    主要从三个方面来讲: 1 单一继承 2 多重继承 3 虚拟继承 1 单一继承 (1)派生类完全拥有基类的内存布局,并保证其完整性. 派生类可以看作是完整的基类的Object再加上派生类自己的Objec ...

随机推荐

  1. rabbitmq延迟队列demo

    1. demo详解 1.1 工程结构: 1.2 pom 定义jar包依赖的版本.版本很重要,rabbit依赖spring,两者必须相一致,否则报错: <properties> <sp ...

  2. 如何消除img默认的间距

    方案一:div{font-size:0};方案二:img{ display:block};方案三:img{vertical-align:top;}方案四:div{ margin-bottom:-3px ...

  3. 彻底解决(Microsoft Visual C++ 14.0 is required)的步骤123

    之前要用协程gevent,安装pip install gevent包时遇到Microsoft Visual C++ 14.0 is required的报错提示,各种下载没有解决很头疼, 前两天安装sc ...

  4. ECMAScript6 入门教程 初学记录let命令 块级作用域

    一.基本语法-let命令 (1)ES6新增了let命令,用来声明变量.所声明的变量,只在let命令所在的代码块内有效. 循环的计数器,就很合适使用let命令.计数器i只在for循环体内有效,在循环体外 ...

  5. 改写pipeline

    为什么要改写方法:get_media_requests,他们的区别在哪里 def get_media_requests(self, item, info):#原始的 return [Request(x ...

  6. MongoSpark 28799错误

    Exception : . The full response is { , "codeName" : "Location28799" } at com.mon ...

  7. FAT32文件系统学习(上)

    2011-06-02 22:30:48 目的:需要编写SD读图片的底层驱动程序.所以要了解一个SD卡常用文件系统基本概念.累计学习用时2.5小时. 一,FAT32的保留区 1,引导扇区 :引导扇区是F ...

  8. java与javax的区别分析(转)

    Java是一种受C语言影响的编程语言.Java和Javax本质上是与Java编程语言的上下文一起使用的包.实际上Java和Javax没有区别.这只是不同的名字. Java是一种编程语言,受到C语言的影 ...

  9. Linux内核 kmalloc, kzalloc & devm_kzalloc 区别【转】

    本文转载自:https://blog.csdn.net/u014628531/article/details/50711409 首先,kzalloc()实现了kmalloc()+memset()的功能 ...

  10. tp未验证内容-9

    在tp的数据库配置中, convention.php中所有的选项都没有设置,要自己在Home/conf/config.php中自己设置, 注意几个地方,一是数据库的名字是: db_name,不是db_ ...