处理 32 位 PowerPC 汇编代码让我感觉非常舒服,但在尝试理解 x86 代码时我完全迷失了方向。ARM、MIPS、Sparc 等其他常见架构是否比 x86 指令集更容易?
9 回答
嗯,大多数 RISC 都非常相似,所以如果您对 PPC 非常了解,那么过渡到 ARM、MIPS 或 SPARC 将是一件轻而易举的事。实际上,我首先学习了 SPARC,然后在几个小时内就掌握了 MIPS 和 PPC。
让 x86 如此混乱的不是它的汇编语言,而是处理器的设计。人们往往会挂断:
- 分段内存寻址——所有这些 ds、cs、es 寄存器:它们是什么意思,它们如何与索引寄存器结合以形成完全解析的内存地址?实际上有三种不同的方式发生,所以你正在学习一堆不同的模式。
- 非正交指令集——一些指令只适用于某些寄存器,其他指令有重叠的含义,有些东西看起来应该很快但真的很慢,等等。
- 寄存器-内存体系结构——x86 被设计成只有少数(命名的)寄存器,因此每个操作码通常有一个参数是寄存器,另一个参数是内存地址。这与 PPC 的加载存储架构不同,其中内存操作是显式的。由于堆栈指针往往会经常反弹,因此很难确定真正使用了哪个变量!
- 痉挛的堆栈指针——大多数 PPC 调用约定让您在进入函数时只移动一次堆栈指针,然后在返回时移动一次,通常 x86 代码将在整个地方进行
push
ing 和ping。pop
您最终会计算推送和弹出来找出堆栈指针到达的位置,这总是让我头疼。
因此,要熟悉 x86,分而治之:选择其中一个点,了解它是如何工作的,然后继续下一个。首先学习调用约定可能会有所帮助,因为这将使引用堆栈指针的所有其他指令更有意义。
如果没有“简单”的定义,我很确定大多数人都会同意 x86 指令集对于主流流行的 CPU 来说是最可怕的。
如果要编写一个在设计指令集时应该遵循的良好或最佳实践列表,x86 将是所有对立面的一个很好的例子。
- 不是正交的,并非所有寄存器的功能都相同。
- 专用寄存器数量有限 - 导致堆栈操作过多。
- 讨厌的前缀运算符。
- ...
我想您应该定义“简单”对您意味着什么。
我宁愿根据正交性来判断机器语言(意思是:指令的任何部分都可以被替代品替换,并且仍然给出有效的指令)
命令(add、sub、mul、div)
参数(寄存器、内存、文字)
参数大小(字节、字、长、浮点)
参数的一致顺序(源 x 源 -> dest,或 dest <- 源 x 源)
和指令的能力/复杂性
可用的寄存器数量
索引寻址
隐式/显式参数
和别的。
也许您应该举例说明与其他架构相比您认为 x86 的哪些部分“不容易”,以及为什么。
ARM,这是从编写汇编程序最后阶段的人的角度来看的。这是帮助您入门的架构参考手册。
编辑:出于某种原因,我认为您的意思是机器代码格式。X86 组装很容易 - 将其组装成机器代码......不是那么多。
我认为您遇到的现象是第二种汇编语言(再次)难以学习(我认为在您开始时学习 PPC 也很困难,那时)。您熟悉的新架构越多,它就越容易 - 在某些时候,您会喜欢发现一些您以前从未见过的架构(错误)功能。
第二种架构的问题是您还不清楚什么是常见的做法,以及第一种架构的特定内容。因此,您希望某些事情在 x86 上完成的方式与在 PPC 上完成的方式相同,而实际上 x86 有自己的(可能甚至更优雅)的做事方式。
我学习了 ARM 汇编,发现它非常简单且功能强大。我不认为将操作数和此类事情混淆。至少因为我先学习了 ARM asm,然后我读了一些关于 x86 asm 的东西。
我发现 x86 上缺少的大多数功能都是 ARM 上的优势点,例如多寄存器存储/读取和条件执行。另外,我发现拥有这么多寄存器非常有帮助。
我认为这是通常的“宗教战争”RISC vs CISC,ARM vs x86。恕我直言,过于主观,无法成为普遍原则。例如 Martin v. Löwis 认为 ARM 不优雅,而我发现它比 x86 优雅得多。
我还试了一下微控制器 asm(Texas Instruments,不记得确切的型号名称),发现它非常不雅,而许多其他人可能会发现它是“完美”的 asm。
魔鬼代言人捍卫 x86 架构
我不会为MS x86 汇编器本身辩护,但请参阅此处了解我的评论。(您可能想使用 gnu ,可能通过Cygwin。)当然,缺少寄存器,它们中的大多数具有特殊用途的性质,以及整个事物的奇怪,扭曲,非正交组织似乎确实代表一个经典的不要这样做的例子。哦,等等,没有人想要或从未真正使用过的极其复杂的极其复杂的功能怎么样?你知道,分割单元?
关于学习的难度,我认为编写 x86 程序集很有趣,尽管我不能完全说明为什么会这样。没有指令集架构真的那么复杂,所以我认为你将能够通过相当小的努力来理解 x86,尽管我同意它肯定比 RISC ISA 有更多的元素。但它很有趣,一些异常细分的寄存器,一些其他特殊用途的寄存器,以及一些指令格式,但大多使用相同的 1.5 地址格式。
回到防守:
关于缺少寄存器:这最终无关紧要。甚至RISC
架构最终也进行了注册重命名,尽管他们有大量的架构寄存器,但它们仍然需要更多的性能。所以 x86 可能会更好,因为每个人都会获得数以万计的自动重命名的,但 x86 只需要保存少量的 arch 寄存器。
在复杂的 ISA 上:英特尔总是处理这个问题,起初是使用强力的高级处理技术(286 在当时非常快),今天通过翻译:RAM 中的 x86 操作码在读入缓存时被转码为微操作,从而将 CPU 内核与 x86 隔离!今天,x86 是一种“指令压缩”方案,只是一种在 CPU 读取程序代码时解开的编码。他们拆分指令的东西,有时它们组合连续的指令,有时它们只是翻译它们。
与ARM一起去。在做了 20 多年的软件工程师之后,我每天都在为各种平台编写汇编程序,但从不需要编写 x86 汇编程序。部分是因为它太可怕了,部分是因为我永远不会嵌入 x86,所以我只运行带有 x86 和 C 的台式机/笔记本电脑,或者你想在 linux/windows 上运行的任何东西都足够低级。
RISC-V可能值得一看。
它是一个开源指令集,旨在易于实现并对现实世界的硬件有用。
它被设计成模块化和可扩展的,“核心”指令集只处理整数,浮点数是扩展。
它支持 32 位、64 位甚至 128 位指令。还有一个 16 位“压缩”变体(尽管目前正在开发中)。默认情况下,您会获得 32 个寄存器。
这是规格。
还有不错的软件支持。例如 Linux、GCC、qemu。
不同供应商目前正在进行多种实施,并得到了谷歌、惠普和甲骨文的支持。有芯片和 FPGA 的开源设计。
当然,如果你从职业生涯的角度来看,RISC-V 在这一点上还处于早期阶段。但由于它是开放的,它可以相当快地增长。