14

我想学习 x86 指令集架构。我的意思不是学习 x86 的程序集。想看懂机器码宝贝。

原因是我想为 x86 编写一个汇编程序。然后我想编写一个编译器来编译该程序集。

我知道有涵盖 x86 指令集的Intel 手册和 AMD 手册。但它们非常大而且密集。

我想知道是否有更平易近人(可能是教程)的方法来学习 x86 指令集架构。

4

6 回答 6

22

好吧,我不同意你的看法。x86 的复杂性被误解,因此被夸大了。我并不是说它不复杂。肯定是这样,但只有在想要编写一个成熟的编译器或汇编器时才会如此。如果你只是想学习汇编。它没有那么复杂。

让我们分解 x86-64 架构来证明我的观点。


寄存器:

x86-64 指定的寄存器很少。具体有多少?让我们列举它们

  • 16个通用寄存器(RAX、RBX、RCX、RDX、RSI、RDI、RBP、RSP + R8、R9、R10、R11、R12、R13、R14、R15)
  • 6个段寄存器(CS、DS、SS、ES、FS、GS)
  • 64 位 RFlags 和 64 位 RIP
  • 8 个 80 位浮点 (x87) 寄存器 (FPR0-FPR7) 别名为 64 位 MMX 寄存器 (MM0-MM7)
  • 16个128位扩展媒体寄存器(XMM0-XMM7 + XMM8-XMM16)
  • 一些特殊/杂项寄存器,例如控制寄存器(CR0 到 4)、调试寄存器(DR0 到 3,加上 6 和 7)、测试寄存器(TR4 到 7)、描述符寄存器(GDTR、LDTR、IDTR)和任务寄存器(TR)我们几乎不需要关心。

替代文字 http://www.viva64.com/content/articles/64-bit-development/amd64_em64t/01-big.png


寻址模式:

如何引用任何内存位置?

来源:http ://en.wikipedia.org/wiki/X86#Addressing_modes

32 位或 64 位 x86 处理器上 32 位地址大小的寻址模式可以通过以下公式进行总结:

替代文字

64 位 x86 处理器上 64 位代码的寻址模式可以通过以下公式进行总结:

替代文字

RIP + [位移]


操作模式:

这些是它可以运行的模式:

  1. 实模式
  2. 保护模式
    • 虚拟 8086 模式
  3. 长模式

指令系统:

你听到人们说它是一个庞大的指令集。好吧,大约有 500-600 条指令。但其中一些是相同的指令,变化很小,如 CMPS/CMPSB/CMPSW/CMPSD/CMPSQ。如果你像这样对它们进行分组,这个数字可以归结为 400 条指令。

你觉得它很大吗?然后我有几个问题。C 标准库有多少个函数?POSIX 库有多少功能?.NET 和 Java 怎么样?他们有多少类和方法?我们必须知道所有的函数/方法/类吗?我们采用什么方法来学习这些库?

只是从每个人身上学到一些东西。大致浏览所有这些。感受它们的存在并在需要时使用参考。

我们可以在逻辑上将这些指令分为以下几类:

  1. 通用指令
    • 基本数据操作(移动和复制)
    • 控制转移(跳转、调用、中断)
    • 算术和逻辑指令(加、减、与、异或等)
    • 面向字符串和位的指令
    • 系统调用
  2. 系统说明
  3. x87 浮点指令
  4. 64 位媒体 (MMX) 指令
  5. 128 位媒体 (SSE) 指令

而已!!这就是你需要知道的一切。现在坦率地告诉我。有那么复杂吗?

随便找一本关于 x86 架构的汇编语言的好书。我个人建议Rajat Moona 撰写的“用于 IA32 架构的 GNU/Linux 中的汇编语言编程”,因为它简短而切题。不会浪费你太多时间。但它不包括 X86-64。

熟悉 IA32 for x86-64 后阅读http://csapp.cs.cmu.edu/public/1e/public/docs/asm64-handout.pdf

于 2010-05-11T19:19:14.943 回答
6

在某些时候,您将不得不应对一些复杂性。x86 指令集很大。

但是您可以通过阅读旧 CPU 的文档来使事情变得更简单。英特尔和 AMD 似乎为每个子模型添加了数十条新指令。尝试阅读80386 的英特尔手册,该手册要小得多,但涵盖了您将使用的大部分内容。

我知道一本好(旧)书,但它是法文的。它被 J.-M 称为“Programmation du 80386”。和 M. 三重奏。我不确定它现在是否还在编辑(我近 20 年前买了我的)。

于 2010-03-18T15:04:17.730 回答
2

我会说跳到深水,然后从那里开始。

首先编写一个简单的 (C/++) 应用程序。然后使用名为 OllyDbg ( http://www.ollydbg.de/ )的史诗调试器。调试您的应用程序并查看编译器如何实现您的代码。检查循环。检查函数调用。检查 API 调用。检查内存操作。

通过这样做,您将真正了解如何做事。

我一直在以这种方式调试应用程序并学习汇编。你说你想理解机器代码,我认为没有更好的方法。

你也可以检查一下名为“crackme”的东西(谷歌它)。这将使您面临考验技能的挑战。一旦你掌握了控制权,你会发现你想知道的一切都只是挖掘说明集手册的问题。明白这点?用特定的目标挑战自己。

祝你好运。这并不容易,但很有可能。

于 2010-03-18T19:32:46.803 回答
1

旧版本的 NASM 手册有一个很好、简洁的参考,尽管它们所指的 CPU 很旧,但它们只是最近才出现的。这是我找到的随机副本。列出操作码(排列以使模式易于查看),并描述寻址模式编码:

http://www.posix.nl/linuxassembly/nasmdochtml/nasmdoca.html

我基本上只使用这些信息编写了一个运行时机器代码生成器(针对 486 或更好),所以那里应该有足够的信息让你开始......

于 2010-05-11T19:29:59.423 回答
1

如果您只想了解数字和一些复杂性,例如 Mod R/M 字节和其背后的其他奇怪之处,您可能想尝试实现一个简单的 8086 仿真器。(只是 CPU)。我发现这是一次有趣而有趣的经历。

http://www.ousob.com/ng/iapx86/是我在编写模拟器时使用的一个非常好的参考,它提供了一个非常好的操作码列表以及它出现的 CPU 版本,以及每个变体的十六进制操作码操作码。

于 2010-03-18T15:00:46.933 回答
0

我觉得你不现实。你sed:

我知道有涵盖 x86 指令集的 Intel 手册和 AMD 手册。但它们非常大而且密集。

...

我想学习所有这些。也许我应该从最简单和最容易学习的东西开始。

你有没有问过自己为什么有大而密的?答案很简单!如果我们只是在寻找 Intel x86 产品

  • 有:8086、8088、80186、80188 和 80286 16 位 CPU。
  • 有: 80386 和 80486 构建浮点协处理器 32 位 CPU。
  • 有:奔腾和奔腾MMX
  • 有:Pentium Pro、Pentium II 和 Pentium III
  • 有:Pentium 4 Pentium M, Pentium 5, Pentium 6, Celleron, Prescott
  • 有:英特尔酷睿2、英特尔酷睿i7
  • 有:Intel Atom
  • 有:沙桥

  • 有 16、32 和 64 位架构

  • 浮点单元有几种不同的数学运算。
  • 有几个流式 SIMD 扩展。
  • 有几种受保护的 CPU 型号。

有...

x86架构研发32年。 而且我没有提到AMD,VIA等等!

不,没有更快的方法!

于 2010-03-18T19:11:36.797 回答