我目前正在研究安德鲁·阿佩尔在Java中的现代编译器实现,我正在构建低级别的中间表示。
一开始,我决定把目标对准JVM,忽略所有的低级机器,但为了学习一些我不太了解的东西,我改变了主意。这改变了我的IR,因为以JVM为目标允许我(或多或少)在进行方法调用或构造对象时挥手。
阿佩尔的书并没有详细介绍任何特定的机器架构,所以我想知道在哪里可以找到我需要知道的东西才能走得更远。
我现在需要知道的是:
以资源代替答案的链接是完全受欢迎的。
发布于 2010-03-02 00:05:36
大多数x86指令集对所有处理器来说都是通用的--这是一个相当安全的打赌,即您的处理器都有相同的指令集,除了可能的SIMD指令在实现简单的编译器时可能不太有用(这些指令通常用于使多媒体应用程序更快地运行)。指令集列在英特尔手册 -- 2A和2B中,特别是完整的指令列表和它们的行为,尽管其他卷值得一看。
在生成用户空间代码时,操作系统的选择对syscalls很重要。例如,如果希望程序在64位Linux上向终端输出某些内容,则需要通过以下方式进行系统调用:
rax以指示这是一个write系统调用。rdi以指示应该使用stdout (1是stdout的文件描述符)rsi中rdx中syscall指令。来自write的返回值存储在rax中。
不同的操作系统可能对write有不同的系统调用号,可能有不同的传入参数的方式(x8664 Linux系统调用总是按照参数的顺序使用rdi、rsi、rdx、r10、r8和r9,系统调用号在rax中),并且可能具有完全不同的系统调用。
Linux上的普通函数调用的惯例是相似的--寄存器的顺序是rdi、rsi、rdx、rcx、r8和r9 (所以,除了使用rcx而不是r10),堆栈上还有更多的参数,并且在rax中有一个返回值。根据此页,应该在函数调用之间保存寄存器rbp、rbx和r12直至r15。当然,您可以自由地制定自己的约定(除非进行系统调用),但这使得从他人生成或编写的代码中调用调用变得更加困难。
发布于 2010-03-02 00:02:45
如何组织堆栈帧等。什么时候使用寄存器而不是把参数放在堆栈上,调用者保存还是被调用者保存,所有这些。我原以为这会和指令集一起描述,但到目前为止,我还没有在任何地方看到这个特定的信息。也许我在这里误会了什么?
一般来说,这些问题没有正确的答案。您可以使用您想要与其他人的代码进行互操作的任何want...unless调用约定。为了实现互操作性,编译器对应用程序二进制接口进行标准化。我的理解是,近年来,Itanium C++ ABI已成为一种流行的标准。试着从那里开始。
发布于 2010-03-02 00:04:27
我不能回答你们所有的问题,但是
https://stackoverflow.com/questions/2360012
复制相似问题