2009-01-17 46 views
11

在学校,我们一直在用MIPS汇编语言进行编程。我有兴趣钻研x86汇编,我听说这有点难(甚至我的MIPS教科书也这么说)。从MIPS切换到x86汇编时应该知道什么?

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

回答

14

要记住最重要的事情是:

  • 很少通用寄存器,并且你有哪些不是纯粹的GP - 许多指令要求使用特定的寄存器用于特定目的。
  • x86指令是双操作码形式而不是三操作码,它可以使某些操作更加复杂。也就是说,不是添加r0,r1,r2(r0 = r1 + r2),而是添加eax,ebx(eax + = ebx)。
  • 保护模式下的段(DOS以外的所有32位代码,有效地)使你的内存寻址方案非常不明显,当你开始时它可以咬你。
  • 您将一直在查看通过指令设置/清除的标志。学习爱英特尔手册。
  • 编辑,我忘了一件事:使用子寄存器(例如ah来访问eax寄存器的低16位的高8位)可以使对寄存器的跟踪操作变得非常困难。小心并且大胆地评论,直到你把事情弄糟。

除此之外,x86非常简单。当你学会滥用像'lea'和'test'这样的指令时,你会学会去爱它。此外,protip:英特尔会免费向您发送指令集手册的副本,甚至无需支付运费。浏览他们的网站以获得履行电子邮件并通过SKU索取书籍。

5

与大多数其他体系结构相比,x86的可用寄存器集非常有限。这并不能真正使汇编语言学得更难,但有时会使实现代码变得更加困难。另外,由于x86具有强大的向后兼容性的历史,指令集不是非常对称的(绝对是RISC之前的),并且可能有很多例外情况需要注意规则和边界情况。

+0

是的,但与MIPS相比并不是那么有限。 :) – BobbyShaftoe 2009-01-17 21:34:15

+3

@BobbyShaftoe,你是程序员吗?据我所知,MIPS有32个通用寄存器,x86有8个。 – mmcdole 2009-01-17 21:41:10

1

x86比MIPS拥有更复杂的指令。所以在MIPS中可能有一条指令用于共同序列(最显着的是内存寻址)。缺少大量的寄存器肯定是一个缺点,但是在两种体系结构中都有一些约定,这些约定几乎将可以自由使用的数量限制在4-5之间。在x86中更加明显。对于注册表使用情况,x86比MIPS有更多的例外,你必须记住,但是没有什么值得一直抱怨的。

从经验说起,任何一种语言都有相同的学习难度,包括惯例。考虑到丰富的在线资源及其受欢迎程度,也许x86更容易一点。

关于x86的难点在于生成二进制,因为它的可变长度指令和几种寻址模式。大多数情况下,你永远不需要这样做。

我当然可以推荐你学习比MIPS更复杂的指令体系结构。

而且,这很重要,不要成为RISC诉诸宗教战争的一部分。 CISC ...

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位GPRS(按顺序):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年背后的所有混乱起因,令人惊讶的是它不会更糟,从第一次推出IA-32起的31年和24年就是这样。很多事情在那个时候改变了他们的相关性。

直接跳转和调用似乎是在x86的下一条指令相对。因此:

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

结束编码为'JMP imm:0,NOP'。绝对跳转的寄存器间接jmp。我们也很高兴地注意到没有寄存器间接的有条件跳转,它也困扰着我。

这里是不是一切可能,你应该知道,但第一个东西,进入我的脑海从你的问题。但也许你现在可以与这些相处。