不同汇编语言的对比

不同汇编语言的对比

在学习汇编语言的过程中, 我们会听到很多很多关于汇编语言的名词, 比如NASM汇编, AT&T风格汇编, ARM汇编, 而大多国内教材教授的都是基于x86平台的MASM汇编语言, 由于缺少对其他汇编语言的介绍, 我们学习完教材后仍然对其他汇编语言的概念和名词不太了解, 导致见到这些名词时一头雾水, 本文旨在通过整理各种资料解释这些名词的含义及区别


实际上我们看到的汇编语言都是 编译器+风格+架构的组合

比如大部分国内教材使用的基于x86平台的MASM汇编语言就是:MASM+Intel风格(涵盖在MASM里)+x86架构

因此我以这三个范畴来区分我们看到的汇编语言的概念和名词

1. 语言/编译器

举例masm, nasm, tasm, yasm

主要区别: 编译器不同, 输出格式不同, 伪指令不同, 宏不同, 支持操作系统平台不同

1. MASM:

微软经典产品,仅支持Windows平台,唯一完美支持按需编译的编译器,不支持输出bin格式。非绿色软件,受版权限制不能二次发行(SASM二次发行了多个汇编编译器唯独没有MASM)。

2. NASM:

一直在持续更新的经典产品,跨平台,支持多种输出格式(bin/coff/omf/elf/…)。有不少衍生品如YASM,可那些衍生品还不如本尊NASM命长。

3. FASM:

还在更新,跨平台,支持多种输出格式(包括bin)。作者在汇编GUI领域走的非常远(参见Fresh IDE及其freshlib),我个人感觉有点偏离汇编正途,用力用错了方向,嘿嘿(我用C++/QT写GUI都嫌麻烦更不要说汇编)。

4. GoASM:

仅支持Windows平台,不支持输出bin格式。作者很有想法,做了大量工作简化Windows应用开发。缺点是加入太多自己的东西,有绑架用户的嫌疑,不利于编写可移植代码。JMP label生成长跳转(E9)而不是短跳转(EB)让我挺无语(见下文代码,其文档中视之为unique label)。

2. 汇编风格

举例Intel风格, AT&T风格

主要区别: 立即数,寄存器的表示方式不同, 数据宽度的表示方式不同,

Intel风格, AT&T风格差异对比:

Win家一般使用Intel风格, 开源界和类Unix系统一般使用AT&T风格

1. 寄存器命名 %

AT&T风格中,寄存器会加上%作为前缀.而Intel汇编中寄存器名是不需要加前缀的.可以直接使用.

AT&T风格Intel风格说明
push %eaxpush eax这是一条入栈指令,把寄存器eax中的值压入栈中

2. 立即数格式 $

  • AT&T 汇编中 , 用$前缀表示一个立即数.
  • Intel 汇编中 , 立即数没有任何前缀. 直接用一个数字表示. (当然有不同的进制. 比如 0x01 , 10 等)
AT&T风格Intel风格说明
push $1push 1把一个立即数压入栈中

3. 操作数顺序

AT&T和Intel格式中的源操作数和目标操作数的位置正好相反
下面是给寄存器EAX 赋一个初值1.

  • AT&T风格: 操作符 源操作数 , 目的操作数
    mov $1 , %eax
  • Intel风格: 操作符 目的操作数 , 源操作数
    mov eax , 1
AT&T风格Intel风格说明
push $1push 1把一个立即数压入栈中

4. 内存操作数的寻址方式

  • AT&T寻址格式: section:disp(base, index, scale)
  • Intel 寻址格式: section:[base + index*scale + disp]

无论形式如何,都是实现如下的地址计算:(其中base和index必须是寄存器,disp和scale可以是常数)
disp + base + index * scale
中文释义: 地址或偏移 (%基址或偏移量寄存器, %索引寄存器, 比例因子)
计算方法: 最终地址 = 地址或偏移 + %基址或偏移量寄存器 + %索引寄存器 * 比例因子
寻址参考: AT&T汇编语言及其寻址方式

AT&T格式Intel格式
movl -4(%ebp), %eaxmov eax, [ebp - 4]
movl array(, %eax, 4), %eaxmov eax, [eax*4 + array]
movw array(%ebx, %eax, 4), %cxmov cx, [ebx + 4*eax + array]
movb $4, %fs:(%eax)mov fs:eax, 4

注: 关于寻址中的段寻址知识参考:
目前在Linux环境上,不管是32位还是64位操作系统段寻址都被废弃. 直接使用的线性地址. 不过fsgs在特殊情况下还有使用.

5. 数据宽度表示

  • 在AT&T汇编格式中,操作数的字长由操作符的最后一个字母决定,
    后缀bwl分别表示操作数为字节(byte,8比特)、字(word,16比特)和长字(long,32比特);
  • 而在Intel汇编格式中,操作数的字长是用byte ptrword ptr等前缀来表示的
AT&T格式Intel格式
movb val, %almov al, byte ptr val

3. 指令集架构(ISA)

举例x86, ARM

主要区别就是支持的机器指令不同, 直接导致机器指令助记符不同, 机器指令在处理器内部的实现方式不同, 对操作数的限制不同

比如ARM 支持通过两条指令 LDR 和 STR 访问内存, 而X86汇编的大部分指令都支持访问内存

平台介绍:

1. x86

早期,1980s年代,x86一般指当时的处理器8088和80286,不过这两个处理器都是16位的。如今,x86通常指32位指令集架构的处理器,比如80386。80386处理器是intel在1985年实现的第一款32位指令集架构的处理器,又叫i386,Intel Architecture, 32-bit,缩写为IA-32,现在,IA-32一般又能引喻成所有的支持32位计算的x86架构。

按照发展历史看,x86应该是指令集概念,一般用于个人PC系统如8086,286,386。IA-32是intel首推的32位架构。

2. x86-64/x64/amd64/Intel64

在1999年,AMD公司首先在IA-32基础上,增加了64位寄存器,兼容早期的16位和32位软件系统,推出了x86-64的64位微处理器,后来命名为AMD64,实现了超车。然后intel公司也接受了该方案,叫做Intel64。x86-64应该只算是x86指令集的64位扩展,并不是一种全新的64位架构。

由于amd64和intel64本质上是一样的,叫法也是很多。AMD通常叫它x86-64、x86_64,微软和sun等软件公司叫它x64,操作系统厂商则通常用AMD64或者amd64来指代AMD64和Intel64。

3. IA-64

IA-64是Intel推出的用于Itanium处理器(安腾处理器)的自己的Intel Architecture 64位指令集,一般用于服务器。尽管Intel64也是64位处理器,但这两者完全不是一回事。IA-64软件不能直接运行于Intel64处理器上。x86-64是IA-32指令集的扩展,而IA-64则是完完全全没有一点IA-32影子的独立处理器架构。IA-64需要通过模拟器才能运行IA-32,但是性能大大受影响。

市面上处理器如何区分AMD64和IA-64呢?

市面上买的Intel 64-bit的cpu其实都属于amd64分类,intel64和amd64其实都应该叫做x86_64。
IA64则指Itaniums系统cpu,并不是x86架构的,一般都是用于服务器,不是个人桌面产品,价格昂贵。

4. ARM64/AArch64

ARM是精简指令集RISC下的处理器架构。ARMv3至ARMv7支持32位寻址空间。ARMv8-A开始支持64位寻址空间。AArch64和ARM64都是指64位的ARM架构。

  • 24
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值