从MIPS切换到x86汇编时应该知道什么?

时间:2009-01-17 21:20:31

标签: assembly x86 mips

在学校,我们一直使用MIPS汇编语言进行编程。我有兴趣深入研究x86程序集,我听说这有点困难(甚至我的MIPS教科书也说过这个)。

在进入x86世界之前,我应该了解哪些核心信息作为MIPS程序员?

4 个答案:

答案 0 :(得分:14)

要记住的最重要的事情是:

  • 很少有通用寄存器,而您拥有的通用寄存器不是纯GP - 许多指令要求您将某些寄存器用于特定目的。
  • x86指令是双操作码形式而不是三操作码,这可能使某些操作更复杂。也就是说,不是添加r0,r1,r2(r0 = r1 + r2),而是添加eax,ebx(eax + = ebx)。
  • 受保护模式中的段(DOS之外的所有32位代码,有效)会使您的内存寻址方案非常明显,这可能会在您开始时咬你的屁股。
  • 您将一直查找由指令设置/清除的标志。学会爱上英特尔手册。
  • 编辑,我忘记了一件事:使用子寄存器(例如,访问eax寄存器的低16位的高8位)可能会使对寄存器的跟踪操作变得非常困难。请小心并大声评论,直到事情发生。

除此之外,x86非常简单。当你学会滥用'lea'和'test'等指令时,你会学会喜欢它。另外,protip:英特尔将免费向您发送指令集手册的副本,甚至不必支付运费。查看他们的网站上的履行电子邮件,并通过SKU索取书籍。

答案 1 :(得分:5)

与大多数其他架构相比,x86具有非常有限的可用寄存器集。这并没有真正使汇编语言更难学习,但有时会使实践中的代码变得更难。

此外,由于x86具有强大的向后兼容性的历史,指令集并不是非常对称(肯定是RISC之前的版本),并且规则和角落案例可能有很多例外需要注意。

答案 2 :(得分:1)

x86具有比MIPS更复杂的指令。因此,MIPS中的公共序列可能只有一条指令(最值得注意的是内存寻址)。缺少大量的寄存器肯定是一个缺点,但在这两种架构中都有一些惯例,这些约定几乎限制了你可以自由使用的数量到4-5。在x86中更加明显。对于寄存器使用,x86有更多的例外,而不是MIPS,你必须牢记这一点,但没有什么值得抱怨的。

根据经验,任何一种语言都有相同的学习难度,包括约定。考虑到丰富的在线资源及其受欢迎程度,x86可能更容易。

关于x86的困难部分是生成二进制文件,因为它具有可变长度指令和几种寻址模式。大多数情况下,你无论如何都不需要这样做。

我当然可以建议你学习比MIPS更复杂的指令架构。

而且,这很重要,不要成为RISC vs.s之间宗教战争的一部分。 CISC ...

答案 3 :(得分:1)

我一直在学习x86和x86_64自己写一个汇编程序。如果你不打算自己编写汇编程序,那么我要说的一些内容几乎没用。我虽然不知道MIPS。

x86间接寻址是一件复杂的事情。在一条指令中,您可以执行以下操作:

mov reg, [reg+offset]
mov reg, [reg*scale+base register+offset] # in where scale can be 1, 2, 4 or 8.

由于这一点,它们的指令编码很复杂,但对于每种编码方式的指令都是一致的。您可能想要从sandpile.org阅读此内容。如果您想了解有关编码的更多信息,可以随时向我询问。编码相关恼人细节的另一指令是前缀。他们经常改变指令的含义。例如,前面是0x66(如果我没记错的话),有些指令适用于16位GPR而不是32位GPR。

32位GPR(按顺序):eax,ecx,edx,ebx,esp,ebp,esi,edi

64位GPR:rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi,r8,r9,r10,r11,r12,r13,r14,r15

注意有多少通用寄存器,这将迫使大多数软件以堆栈机器方式或多或少地使用它。一个痛苦的细节。 rsp用于堆栈(pop,push -instructions),并且rbp也倾向于保留。 x86_64有更多的寄存器,但人们采用它会花费时间,即使每个消费者都有一个能够处理它的处理器。

浮点运算有两种不同的指令集。 XMM是更新的。在x86_64中有16个128位寄存器可用,在x86中只有8个寄存器。较旧的指令集将寄存器作为堆栈处理。你只是没有交换,捏或腐烂,所以使用它是令人费解的。

在使用中,x86倾向于减少为RISC机器。其中一些复杂的指令不会给新机器带来好处,甚至更慢。根据您的阅读或写作内容,您将了解30-150条指令。您也可以完全忽略一些旧指令和AL / HL -stuff。请记住1978年背后的所有混乱的起源,这是非常令人惊讶的,它不会更糟,31年后和首次推出IA-32后的24年。很多事情都改变了它们在那个时代的相关性。

直接跳转和调用似乎与x86中的下一条指令相关。因此:

    jmp nowhere  # or call, jz, jg whatever...
nowhere:
    nop

结束编码为'JMP imm:0,NOP'。寄存器 - 间接jmp确实执行绝对跳转。注意到没有寄存器间接条件跳转也很好,这也让我感到困扰。

这不是你应该知道的所有事情,而是你问题中我想到的第一件事。但也许你现在可以相处这些。