Assembly lisp是如何在汇编语言中实现的?

Assembly lisp是如何在汇编语言中实现的?,assembly,lisp,implementation,convention,Assembly,Lisp,Implementation,Convention,许多(可能是全部?)编程语言由汇编语言组成 lisp是如何在汇编语言中实现的 谷歌有什么好的参考资料、手册、教程或关键词吗 构建自己的lisp实现是否有任何官方规则/约定 比如尾部递归应该遵循一些具体的规则或者什么 谢谢你,这是一个需要很好回答的大问题 简短回答: 大答案:。你的问题基于非常过时的假设。现在,几乎没有语言实现是用汇编语言编写的,据我所知,也没有Lisp实现是用汇编语言编写的。除了自托管实现之外,C语言现在是一种通用的实现语言 如果您想查看lisp函数的汇编语言表示,有一个问题。我

许多(可能是全部?)编程语言由汇编语言组成

lisp是如何在汇编语言中实现的

谷歌有什么好的参考资料、手册、教程或关键词吗

构建自己的lisp实现是否有任何官方规则/约定

比如尾部递归应该遵循一些具体的规则或者什么


谢谢你,这是一个需要很好回答的大问题

简短回答:


大答案:。

你的问题基于非常过时的假设。现在,几乎没有语言实现是用汇编语言编写的,据我所知,也没有Lisp实现是用汇编语言编写的。除了自托管实现之外,C语言现在是一种通用的实现语言


如果您想查看lisp函数的汇编语言表示,有一个问题。

我在过去考虑过一点(然后改用C内核)。当然,没有单一的“汇编”,但对于x86/32位,这就是我的计划:

基本值存储在64位节点中,最低的三位用作标记,含义如下:

000 -> cell (64 bits are basically two pointers: car/cdr)
001 -> fixnum (64-3-1 bits usable for values)
010 -> vector (32-3 bits for size and 32 bit for pointer to first element)
011 -> symbol (32 bits pointing to values in global env, 32 pointing to name)
100 -> native code (32 bits pointing to executable machine code, 32 bits to args)
101 -> float (using 64-3-1 bit by dropping 4 bits from mantissa)
110 -> string (using 32-3 bits for size and 32 bits pointing to bytes)
111 -> struct (32 bits pointing to definition, 32 bits pointing to content)
如果假设所有分配都是8字节的倍数(单元大小为8字节时合理),则在考虑指针时,3位仍然可用。实现一个简单的垃圾收集器需要一个额外的位(“活动”位)。在C实现中,我最终根据节点类型将该位分配到不同的部分(例如,较高32位的最低有效位,如果是指针)

我的想法是拥有两种类型的内存:“节点内存”(具有上面描述的布局)在页面中分配并与空闲列表一起重用,以及“二进制内存”用于可变大小的字符串/代码/数组

根据节点类型,需要特定代码来实现递归标记为活动节点引用的活动节点的
touch
功能


所有这些当然只是一种幼稚的方法,但我仍然在“C”中使用它,我确信我也可以在汇编中使用它(我的C代码在任何地方都使用
void*
,因此基本上只是一个可移植的32位汇编程序)。在我的C实现中,我只使用了32位作为浮点和整数(使用较高的32位),而没有使用所有可用的位。

尽管其他评论和帖子都是正确的,但这个问题过于模糊,可能有点困惑,我不得不分享一些建议。我收集了许多关于实现Lisp的链接和书籍,因为我最近对语言实现有点着迷。当然,这是一个很深的话题,但是阅读与Lisp相关的内容尤其引人注目,因为如果在Lisp中实现Lisp编译器或解释器,只需使用
read
,就可以跳过大量有关解析的密集阅读。这使作者能够快速地获得编译或解释的内容。这些推荐书是我已经读过、开始读过或正在读的书,主要涉及Scheme,而不是CommonLisp,但可能仍然有一些兴趣

如果您没有语言实现方面的背景,并且从未有幸阅读过经典的Lisp和Scheme“元循环评估器”,我会推荐您。如果您在Lisp中看到Lisp(或Scheme中的Scheme…),可以跳过前面的步骤。在SICP的最后两章中,作者介绍了几个不同的Lisp/Scheme解释器和几个变体,以及一个字节码编译器和一个虚拟机。这只是一本精彩的书,而且是免费的

如果您没有时间阅读SICP,或者不想为了阅读解释和编译章节而费劲地阅读它,我会推荐您。尽管这本书很短,是为Lisp和Scheme的新手准备的,但如果您从未见过用Lisp编写的Lisp解释器,他们会提供一本,这本书非常有趣,但由于其可爱的风格,可能并不适合所有人

还有另一本关于Scheme的免费书,类似于SICP,叫做,我还没有读过,但作为一些参考。其中有关于解释器和编译器的部分,它似乎比SICP更深入,处理更复杂的事情,比如解析。它可能需要一个编辑,但它仍然是一个令人印象深刻的产品

有了关于如何在Lisp中实现Lisp的好主意,您可以在较低的级别上实现Lisp

这是经常被推荐的。我读了大部分,可以说这绝对是一本很棒的书,充满了细节。我会仔细回顾一遍,因为当你不懂东西的时候很容易浏览。我还努力让代码从作者的网站上运行;如果您明白了,我建议您使用Gambit方案并从发行版运行依赖于Meroonet和Meroon的代码。Lisp小片段介绍了许多用Scheme编写的解释器,以及一个字节码编译器和一个C到C的编译器

小片段的Lisp移动速度很快,而且非常密集。如果这对你来说太多了,也许从开始。我读过一些,很不错,但更多的是口译员。显然,其中一个较旧的版本(第1版?我不确定…)包含了一个编译器。3个版本之间似乎有很多变化,但第一个版本在亚马逊上非常便宜,所以请查看

至于C语言的编译,这是一个有很多毛茸茸的地方的粗俗主题。编译到C会带来所有这些奇怪的问题,比如如何优化尾部调用和处理闭包、一级延续和垃圾收集,但这非常有趣,Scheme的许多“真实”实现都是这样。Marc Feeley关于这方面的介绍非常有趣,标题为

从编译一直到汇编,我的资源很少,但有一篇经常被推荐的论文介绍了Scheme到x86的编译,称为It because little of the read
(defx86lapmacro %car (src dest)
    (target-arch-case
       (:x8632
          `(movl (@ x8632::cons.car (% ,src)) (% ,dest)))
       (:x8664
          `(movq (@ x8664::cons.car (% ,src)) (% ,dest)))))