Compiler construction 为x86处理器生成程序集

Compiler construction 为x86处理器生成程序集,compiler-construction,assembly,code-generation,x86,Compiler Construction,Assembly,Code Generation,X86,我目前正在用Java完成Andrew Appel的现代编译器实现,我正处在构建低级中间表示的关键点上 起初,我决定以JVM为目标,忽略所有低级机器的东西,但为了学习我不太了解的东西,我改变了主意。这改变了我的IR,因为以JVM为目标允许我(或多或少)在进行方法调用或构造对象时挥挥手 Appel的书没有详细介绍任何特定的机器架构,所以我想知道在哪里可以找到我需要知道的一切,以便进一步了解 我目前意识到我需要知道的是: 要使用的指令集。我有两台笔记本电脑可以开发;两者都有核心2双核处理器。我目前的

我目前正在用Java完成Andrew Appel的现代编译器实现,我正处在构建低级中间表示的关键点上

起初,我决定以JVM为目标,忽略所有低级机器的东西,但为了学习我不太了解的东西,我改变了主意。这改变了我的IR,因为以JVM为目标允许我(或多或少)在进行方法调用或构造对象时挥挥手

Appel的书没有详细介绍任何特定的机器架构,所以我想知道在哪里可以找到我需要知道的一切,以便进一步了解

我目前意识到我需要知道的是:

  • 要使用的指令集。我有两台笔记本电脑可以开发;两者都有核心2双核处理器。我目前的理解是x86处理器大多使用相同的指令集,但它们并不完全相同

  • 操作系统是否影响编译的代码生成步骤,或者它是否完全依赖于处理器。例如,我知道生成在32位平台上运行的代码与在64位平台上运行的代码有所不同

  • 如何组织堆栈帧等。什么时候使用寄存器,什么时候在堆栈上放置参数,什么时候调用方保存,什么时候被调用方保存,所有这些。我原以为这将与指令集一起描述,但到目前为止,我还没有在任何地方看到这一特定信息。也许我误解了什么

我们非常欢迎链接到资源而不是答案

堆栈框架等是如何工作的 有组织的。何时使用寄存器vs。 将参数放在堆栈上, 调用方保存与被调用方保存,所有 那个我本以为这会 随附说明 指令集,但到目前为止我还没有 在任何地方都可以看到这个信息。 也许我误解了什么 这里


总的来说,这些问题没有正确的答案。您可以使用任何您想要的调用约定…除非您想要与其他人的代码进行互操作。为了实现互操作性,编译器将应用程序二进制接口标准化。我的理解是,近几年来,标准已经成为一种流行的标准。试着从这里开始。

我不能回答你们所有的问题;但是

  • 基本x86指令集为 兼容x86系列的 处理器。你不打算这么做 实施任何特定的扩展, 是吗
  • 我不认为你的操作系统 或者架构对代码来说很重要 世代
  • 默认答案 任何与编译器相关的都是 . 你看过吗 现在好了吗

大多数x86指令集对于所有处理器都是通用的——可以肯定的是,您的处理器都具有相同的指令集,但SIMD指令可能除外,在实现简单编译器时,SIMD指令可能对您没有多大用处(这些指令通常用于使多媒体应用程序和类似程序运行得更快)。在--2A和2B中列出了指令集,其中特别列出了指令及其行为的完整列表,尽管其他卷值得一看

生成用户空间代码时,在系统调用时,操作系统的选择很重要。例如,如果您希望程序在64位Linux上向终端输出某些内容,则需要通过以下方式进行系统调用:

  • 将值1加载到寄存器
    rax
    以指示这是一个
    write
    系统调用
  • 将值1加载到寄存器
    rdi
    以指示应使用标准输出(1是标准输出的文件描述符)
  • 将要打印内容的起始地址加载到寄存器
    rsi
  • 将要打印内容的长度加载到寄存器
    rdx
  • 设置寄存器(和内存)后,执行
    syscall
    指令
write
的返回值存储在
rax

不同的操作系统可能有不同的系统调用号,用于
写入
,可能有不同的传入参数的方式(x86-64 Linux系统调用总是使用
rdi
rsi
rdx
r10
r8
r9
按该顺序作为参数,系统调用号在
rax
中),并且可能有不同的系统调用


Linux上普通函数调用的约定是类似的——寄存器的顺序是
rdi
rsi
rdx
rcx
r8
,和
r9
(因此,除了使用
rcx
而不是
r10
)之外,都是相同的),堆栈上有进一步的参数和
rax
中的返回值。根据,寄存器
rbp
rbx
r12
直到
r15
都应该在函数调用中保留。当然,您可以自由地制定自己的约定(除非进行系统调用)但是,这使得调用别人生成的代码或编写的代码变得更加困难。谢谢,弥敦。我不太明白ItAuthC++ C++的目的是什么,这与我的目的有关(例如,C++在开发编译器的过程中扮演了什么角色?);然而,这个链接最终让我找到了各种x86调用约定(cdecl等)这正是我想要的。谢谢你,迈克尔-这个答案也很有帮助。我希望我也能接受它;我自己的错是把太多的问题结合在一起了。+1,尽管如此。事实上,第二次读这篇文章时,我认为这篇文章最彻底地回答了我所有的问题。投票结束的范围太广了。