《逆向工程权威指南》—第1章1.1节指令集架构

简介:

本节书摘来自异步社区《逆向工程权威指南》一书中的第1章1.1节指令集架构,作者【乌克兰】Dennis Yurichev(丹尼斯),更多章节内容可以访问云栖社区“异步社区”公众号查看。

第一部分 指令讲解
逆向工程权威指南
在最初接触C/C++时,我就对程序编译后的汇编指令十分着迷。按照从易到难的顺序,我循序渐进地研究了C/C++语言编译器生成汇编指令的模式。经过日积月累的努力,现在我不仅可以直接阅读x86程序的汇编代码,而且能够在脑海里将其还原成原始的C/C++语句。我相信这是学习逆向工程的有效方法。为了能够帮助他人进行相关研究,我把个人经验整理成册,以待与读者分享。

本书包含大量x86/x64和ARM框架的范例。如果读者熟悉其中某一种框架,可以跳过相关的篇幅。


0afa9bbcb89c93b25ee148f4b8d72e4c5b5c9f05

第1章 CPU简介
逆向工程权威指南
CPU是执行程序机器码的硬件单元。简要地说,其相关概念主要有以下几项。

指令码:CPU受理的底层命令。典型的底层命令有:将数据在寄存器间转移、操作内存、计算运算等指令。每类CPU都有自己的指令集架构(Instruction Set Architecture,ISA)。

机器码:发送给CPU的程序代码。一条指令通常被封装为若干字节。

汇编语言:为了让程序员少长白头发而创造出来的、易读易记的代码,它有很多类似宏的扩展功能。

CPU寄存器:每种CPU都有其固定的通用寄存器(GPR)。x86 CPU里一般有8个GPR,x64里往往有16个GPR,而ARM里则通常有16个GPR。您可以认为CPU寄存器是一种存储单元,它能够无差别地存储所有类型的临时变量。假如您使用一种高级的编程语言,且仅会使用到8个32位变量,那么光CPU自带的寄存器就能完成不少任务了!

那么,机器码和编程语言(PL)的区别在哪里?CPU可不像人类那样,能够理解C/C++、Java、Python这类较为贴近人类语言的高级编程语言。CPU更适合接近硬件底层的具体指令。在不久的将来,或许会出现直接执行高级编程语言的CPU,不过那种尚未问世的科幻CPU必定比现在的CPU复杂。人脑和计算机各有所长,如果人类直接使用贴近硬件底层的汇编语言编写程序,其难度也很高——因为那样很容易出现大量的人为失误。可见,我们需要用一种程序把高级的编程语言转换为CPU能受理的底层汇编语言,而这种程序就是人们常说的编译器/Compiler。

1.1 指令集架构
在x86的指令集架构(ISA)里,各opcode(汇编指令对应的机器码)的长度不尽相同。出于兼容性的考虑,后来问世的64位CPU指令集架构也没有大刀阔斧地摒弃原有指令集架构。很多面向早期16位8086 CPU的指令,不仅被x86的指令集继承,而且被当前最新的CPU指令集继续沿用。

ARM属于RISC[1] CPU,它的指令集在设计之初就力图保持各opcode的长度一致。在过去,这一特性的确表现出了自身的优越性。最初的时候,所有ARM指令的机器码都被封装在4个字节里[2]。人们把这种运行模式叫作“ARM模式”。

不久,他们就发现这种模式并不划算。在实际的应用程序中,绝大多数的CPU指令[3]很少用满那4个字节。所以他们又推出了一种把每条指令封装在2个字节的“Thumb”模式的指令集架构。人们把采用这种指令集编码的指令叫作“Thumb模式”指令。然而Thumb指令集并不能够封装所有的ARM指令,它本身存在指令上的局限。当然,在同一个程序里可以同时存在ARM模式和Thumb模式这两种指令。

之后,ARM的缔造者们决定扩充Thumb指令集。他们自ARM v7平台开始推出了Thumb-2指令集。Thumb-2指令基本都可封装在2个字节的机器码之中,2个字节封装不下的指令则由4字节封装。现在,多数人依然错误地认为“Thumb-2指令集是ARM指令集和Thumb指令集的复合体”。实际上,它是一种充分利用处理器性能、足以与ARM模式媲美的独立的运行模式。在扩展了Thumb模式的指令集之后,Thumb-2现在与ARM模式不相上下。由于Xcode编译器默认采用Thumb-2指令集编译,所以现在主流的iPod/iPhone/iPad应用程序都采用了Thumb-2指令集。

64位的ARM处理器接踵而至。这种CPU的指令集架构再次使用固定长度的4字节opcode,所以不再支持Thumb模式的指令。相应地,64位ARM工作于自己的指令集。受到指令集架构的影响,ARM指令集分为3类:ARM模式指令集、Thumb模式指令集(包括Thumb-2)和ARM64的指令集。虽然这些指令集之间有着千丝万缕的联系,需要强调的是:不同的指令集分别属于不同的指令集架构;一个指令集绝非另一个指令集的变种。相应地,本书会以3种指令集、重复演示同一程序的指令片段,充分介绍ARM应用程序的特点。

除了ARM 处理器之外,还有许多处理器都采用了精简指令集。这些处理器多数都使用了固定长度的32位opcode。例如MIPS、PowerPC和Alpha AXP处理器就是如此。

[1] Reduced instruction computing /精简指令集。

[2] 这种固定长度的指令集,特别便于计算前后指令的地址。有关特性将在13.2.2节进行介绍。

[3] 即MOV/PUSH/CALL/Jcc等指令。

本文仅用于学习和交流目的,不代表异步社区观点。非商业转载请注明作译者、出处,并保留本文的原始链接。

相关文章
|
4月前
|
存储 编译器 数据处理
CPU架构和指令集
不同的CPU架构通常使用不同的指令集。每种CPU架构都有其自己的一组特定的机器指令,这些指令用于执行计算机程序。不同的CPU架构之间的指令集是不兼容的,这意味着编写的程序通常需要根据目标CPU的架构进行编译或汇编,以确保它们能够在该CPU上正确运行。 一些常见的CPU架构包括:
|
Linux C语言 Android开发
【C 语言】CPU 架构 ( CPU 指令集类型 | CPU 指令类型 | CPU 架构 )
【C 语言】CPU 架构 ( CPU 指令集类型 | CPU 指令类型 | CPU 架构 )
316 0
|
缓存 安全 Java
|
机器学习/深度学习 缓存 固态存储
硬盘大佬也玩CPU!西部数据公布RISC-V自研架构SweRV及开源指令集模拟器
西部数据预计硬件和软件将用于大数据和快速数据应用的各种解决方案,包括闪存控制器和SSD。
526 0
|
程序员
《操作系统真象还原》——0.25 指令集、体系结构、微架构、编程语言
假设我们的指令格式最大支持三个寄存器参数和一个立即数参数。其中操作码和各寄存器操作数各占1字节,立即数部分占4字节。各条指令并不是完全按照此格式填充,不同的指令有不同的参数,只有操作码部分是固定的,其他操作数部分是可选的。
1987 0