Compiler construction 为x86处理器生成程序集
我目前正在用Java完成Andrew Appel的现代编译器实现,我正处在构建低级中间表示的关键点上 起初,我决定以JVM为目标,忽略所有低级机器的东西,但为了学习我不太了解的东西,我改变了主意。这改变了我的IR,因为以JVM为目标允许我(或多或少)在进行方法调用或构造对象时挥挥手 Appel的书没有详细介绍任何特定的机器架构,所以我想知道在哪里可以找到我需要知道的一切,以便进一步了解 我目前意识到我需要知道的是:Compiler construction 为x86处理器生成程序集,compiler-construction,assembly,code-generation,x86,Compiler Construction,Assembly,Code Generation,X86,我目前正在用Java完成Andrew Appel的现代编译器实现,我正处在构建低级中间表示的关键点上 起初,我决定以JVM为目标,忽略所有低级机器的东西,但为了学习我不太了解的东西,我改变了主意。这改变了我的IR,因为以JVM为目标允许我(或多或少)在进行方法调用或构造对象时挥挥手 Appel的书没有详细介绍任何特定的机器架构,所以我想知道在哪里可以找到我需要知道的一切,以便进一步了解 我目前意识到我需要知道的是: 要使用的指令集。我有两台笔记本电脑可以开发;两者都有核心2双核处理器。我目前的
- 要使用的指令集。我有两台笔记本电脑可以开发;两者都有核心2双核处理器。我目前的理解是x86处理器大多使用相同的指令集,但它们并不完全相同
- 操作系统是否影响编译的代码生成步骤,或者它是否完全依赖于处理器。例如,我知道生成在32位平台上运行的代码与在64位平台上运行的代码有所不同
- 如何组织堆栈帧等。什么时候使用寄存器,什么时候在堆栈上放置参数,什么时候调用方保存,什么时候被调用方保存,所有这些。我原以为这将与指令集一起描述,但到目前为止,我还没有在任何地方看到这一特定信息。也许我误解了什么
总的来说,这些问题没有正确的答案。您可以使用任何您想要的调用约定…除非您想要与其他人的代码进行互操作。为了实现互操作性,编译器将应用程序二进制接口标准化。我的理解是,近几年来,标准已经成为一种流行的标准。试着从这里开始。我不能回答你们所有的问题;但是
- 基本x86指令集为 兼容x86系列的 处理器。你不打算这么做 实施任何特定的扩展, 是吗
- 我不认为你的操作系统 或者架构对代码来说很重要 世代
- 默认答案 任何与编译器相关的都是 . 你看过吗 现在好了吗
- 将值1加载到寄存器
以指示这是一个rax
系统调用write
- 将值1加载到寄存器
以指示应使用标准输出(1是标准输出的文件描述符)rdi
- 将要打印内容的起始地址加载到寄存器
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,尽管如此。事实上,第二次读这篇文章时,我认为这篇文章最彻底地回答了我所有的问题。投票结束的范围太广了。