【问题标题】:LISP 1.5 How lisp is like a machine language?LISP 1.5 lisp 有多像机器语言?
【发布时间】:2013-08-13 22:36:41
【问题描述】:
【问题讨论】:
标签:
lisp
racket
s-expression
machine-language
computer-science-theory
【解决方案1】:
也就是说机器码可以直接将机器指令写入内存并跳转到那些指令执行它们;事实上,这是许多攻击媒介侵入软件的基础。
关键是,当您编写机器代码时,很容易生成机器代码。但是,当您使用 C 之类的编译语言编写代码时,您不能只在运行时生成 C 代码然后执行它——除非您的程序包含 C 编译器。
Lisp - 以及现在许多其他语言,尤其是“脚本语言”,如 Perl、Python、Ruby、Tcl、Javascript 和命令 shell - 能够执行在运行时生成的代码。在 Lisp 中,由于代码和数据具有相同的结构,这通常比在其他语言中的工作量要少,在其他语言中,要评估的代码通常是必须解析的字符串。 (虽然 Perl 有能力 eval 一个块而不是一个字符串,这让编译器可以提前解析文字代码。)
【解决方案2】:
机器语言可以在运行时改变自己。我做的最后一次汇编编程是针对 MS DOS 和我在测试其他程序之前运行的常驻程序。当我的程序出现异常时,按键切换到常驻程序,并且可以查看正在运行的程序并在恢复之前直接对其进行更改。因为我没有调试器,所以很方便。
LISP 从一开始就有这个,因为它最初是被解释的。您可以在运行时更改函数的定义,并且整个语言在运行时始终可用,即使是eval 和define。当它开始编译时,它并没有像 Algol 那样编译,而是部分允许解释和编译的代码同时混合。它的代码结构是列表结构,而符号是一种数据类型,这一事实促成了这一点。
Last interview I saw with McCarthy 有人问他对现代编程语言的看法(不是 LISP 家族,而是据说受 LISP 影响的 Algol 家族语言 Ruby),在回答之前他问他们是否可以将代码表示为数据(比如列表结构)。在他看来,Ruby 仍然落后于 60 年代的 LISP。
Algol 家族中出现了许多新的编程语言,其中一些最有前途的语言,如 Perl6 和 Nemerle,正在接近 60 年代 LISP 的功能。
【解决方案3】:
机器语言程序可以用任意字节填充内存区域。然后他们可以jump 到该区域的开头,从而立即执行。
Lisp 语言程序可以使用cons 在内存中轻松创建任意 S 表达式。然后他们可以在这些 S 表达式上调用 eval 来评估(解释)它们。
高级语言程序可以轻松地用代表语言语法中新代码的字符填充内存区域。但是他们不能运行这样的代码。