首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为x86处理器生成程序集

为x86处理器生成程序集
EN

Stack Overflow用户
提问于 2010-03-01 23:53:32
回答 3查看 747关注 0票数 7

我目前正在研究安德鲁·阿佩尔在Java中的现代编译器实现,我正在构建低级别的中间表示。

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

阿佩尔的书并没有详细介绍任何特定的机器架构,所以我想知道在哪里可以找到我需要知道的东西才能走得更远。

我现在需要知道的是:

  • 使用哪个指令集。我有两台笔记本电脑我可以开发;两者都有Core2Duo处理器。我目前的理解是,x86处理器大多使用相同的指令集,但它们并不完全相同。
  • 操作系统是否影响编译的代码生成步骤,或者它是否完全依赖于处理器。例如,我知道生成在32位平台上运行的代码与在64位平台上运行的代码有些不同。
  • 如何组织堆栈帧等。什么时候使用寄存器而不是把参数放在堆栈上,调用者保存还是被调用者保存,所有这些。我原以为这会和指令集一起描述,但到目前为止,我还没有在任何地方看到这个特定的信息。也许我在这里误会了什么?

以资源代替答案的链接是完全受欢迎的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-03-02 00:05:36

大多数x86指令集对所有处理器来说都是通用的--这是一个相当安全的打赌,即您的处理器都有相同的指令集,除了可能的SIMD指令在实现简单的编译器时可能不太有用(这些指令通常用于使多媒体应用程序更快地运行)。指令集列在英特尔手册 -- 2A和2B中,特别是完整的指令列表和它们的行为,尽管其他卷值得一看。

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

  • 将值1加载到寄存器rax以指示这是一个write系统调用。
  • 将值1加载到寄存器rdi以指示应该使用stdout (1是stdout的文件描述符)
  • 将要打印的内容的起始地址加载到寄存器rsi
  • 将要打印的内容的长度加载到寄存器rdx
  • 一旦建立了寄存器(和内存),就执行syscall指令。

来自write的返回值存储在rax中。

不同的操作系统可能对write有不同的系统调用号,可能有不同的传入参数的方式(x8664 Linux系统调用总是按照参数的顺序使用rdirsirdxr10r8r9,系统调用号在rax中),并且可能具有完全不同的系统调用。

Linux上的普通函数调用的惯例是相似的--寄存器的顺序是rdirsirdxrcxr8r9 (所以,除了使用rcx而不是r10),堆栈上还有更多的参数,并且在rax中有一个返回值。根据此页,应该在函数调用之间保存寄存器rbprbxr12直至r15。当然,您可以自由地制定自己的约定(除非进行系统调用),但这使得从他人生成或编写的代码中调用调用变得更加困难。

票数 5
EN

Stack Overflow用户

发布于 2010-03-02 00:02:45

如何组织堆栈帧等。什么时候使用寄存器而不是把参数放在堆栈上,调用者保存还是被调用者保存,所有这些。我原以为这会和指令集一起描述,但到目前为止,我还没有在任何地方看到这个特定的信息。也许我在这里误会了什么?

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

票数 3
EN

Stack Overflow用户

发布于 2010-03-02 00:04:27

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

  • 基本的x86指令集可以兼容于x86系列处理器。您不打算实现任何特定的扩展,对吗?
  • 我不认为您的操作系统或体系结构对代码生成很重要
  • 任何编译器相关的默认答案都是龙书。你看过了吗?
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2360012

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档