ATT汇编与Intel汇编的区别,摘自《深入分析linux内核源码》一书

2.6.1 AT&T与Intel汇编语言的比较

我们知道,Linux是Unix家族的一员,尽管Linux的历史不长,但与其相关的很多事情都发源于Unix。就Linux所使用的386汇编语言而言,它也是起源于Unix。Unix最初是为PDP-11开发的,曾先后被移植到VAX及68000系列的处理器上,这些处理器上的汇编语言都采用的是AT&T的指令格式。当Unix被移植到i386时,自然也就采用了AT&T的汇编语言格式,而不是Intel的格式。尽管这两种汇编语言在语法上有一定的差异,但所基于的硬件知识是相同的,因此,如果你非常熟悉Intel的语法格式,那么你也可以很容易地把它“移植“到AT&T来。下面我们通过对照Intel与AT&T的语法格式,以便于你把过去的知识能很快地“移植”过来。

1.前缀

在Intel的语法中,寄存器和和立即数都没有前缀。但是在AT&T中,寄存器前冠以“%”,而立即数前冠以“$”。在Intel的语法中,十六进制和二进制立即数后缀分别冠以“h”和“b”,而在AT&T中,十六进制立即数前冠以“0x”,表2.2给出几个相应的例子。

表2.2 Intel与AT&T前缀的区别


Intel语法


AT&T语法


mov     eax,8


movl   $8,%eax


mov     ebx,0ffffh


movl   $0xffff,%ebx


int 80h


int      $0x80

2. 操作数的方向

Intel与AT&T操作数的方向正好相反。在Intel语法中,第一个操作数是目的操作数,第二个操作数源操作数。而在AT&T中,第一个数是源操作数,第二个数是目的操作数。由此可以看出,AT&T 的语法符合人们通常的阅读习惯。

例如:在Intel中, mov    eax,[ecx]

在AT&T中,movl  (%ecx),%eax

3.内存单元操作数

从上面的例子可以看出,内存操作数也有所不同。在Intel的语法中,基寄存器用“[]”括起来,而在AT&T中,用“()”括起来。

例如: 在Intel中,mov    eax,[ebx+5]

在AT&T,movl     5(%ebx),%eax

4.间接寻址方式

与Intel的语法比较,AT&T间接寻址方式可能更晦涩难懂一些。Intel的指令格式是segreg:[base+index*scale+disp],而AT&T的格式是%segreg:disp(base,index,scale)。其中index/scale/disp/segreg全部是可选的,完全可以简化掉。如果没有指定scale而指定了index,则scale的缺省值为1。segreg段寄存器依赖于指令以及应用程序是运行在实模式还是保护模式下,在实模式下,它依赖于指令,而在保护模式下,segreg是多余的。在AT&T中,当立即数用在scale/disp中时,不应当在其前冠以“$”前缀,表2.3给出其语法及几个相应的例子。

表2.3 内存操作数的语法及举例


Intel语法


AT&T语法


指令      foo,segreg:[base+index*scale+disp]


指令       %segreg:disp(base,index,scale),foo


mov    eax,[ebx+20h]


Movl      0x20(%ebx),%eax


add     eax,[ebx+ecx*2h


Addl           (%ebx,%ecx,0x2),%eax


lea      eax,[ebx+ecx]


Leal     (%ebx,%ecx),%eax


sub     eax,[ebx+ecx*4h-20h]


Subl     -0x20(%ebx,%ecx,0x4),%eax

从表中可以看出,AT&T的语法比较晦涩难懂,因为[base+index*scale+disp]一眼就可以看出其含义,而disp(base,index,scale)则不可能做到这点。

这种寻址方式常常用在访问数据结构数组中某个特定元素内的一个字段,其中,base为数组的起始地址,scale为每个数组元素的大小,index为下标。如果数组元素还是一个结构,则disp为具体字段在结构中的位移。

5.操作码的后缀

在上面的例子中你可能已注意到,在AT&T的操作码后面有一个后缀,其含义就是指出操作码的大小。“l”表示长整数(32位),“w”表示字(16位),“b”表示字节(8位)。而在Intel的语法中,则要在内存单元操作数的前面加上byte ptr、 word ptr,和dword ptr,“dword”对应“long”。表2.4给出几个相应的例子。

表2.4 操作码的后缀举例


Intel语法


AT&T语法


Mov     al,bl


movb    %bl,%al


Mov     ax,bx


movw   %bx,%ax


Mov     eax,ebx


movl     %ebx,%eax


Mov     eax, dword ptr [ebx]


movl     (%ebx),%eax

时间: 2024-10-15 07:57:04

ATT汇编与Intel汇编的区别,摘自《深入分析linux内核源码》一书的相关文章

AT&T汇编和Intel汇编语法主要区别

AT&T使用$表示立即操作数,而Intel的立即操作数是不需要界定的.因此,使用AT&T语法引用十进制值4时,使用$4,使用Intel语法时只需使用4.   AT&T在寄存器名称前加上前缀%,而Intel不这样做.因此,使用AT&T语法引用EAX寄存器写为%eax.   AT&T语法处理源和目标操作数时使用相反的顺序.把十进制值4传送给EAX寄存器,AT&T的语法是movl $4, %eax,而Intel语法是mov eax, 4.   AT&T语法

gcc和g++的区别【转自中国源码网】

gcc和g++都是GNU(组织)的一个编译器. 误区一:gcc只能编译c代码,g++只能编译c++代码两者都可以,但是请注意:1.后缀为.c的,gcc把它当作是C程序,而g++当作是c++程序:后缀为.cpp的,两者都会认为是c++程序,注意,虽然c++是c的超集,但是两者对语法的要求是有区别的.C++的语法规则更加严谨一些.2.编译阶段,g++会调用gcc,对于c++代码,两者是等价的,但是因为gcc命令不能自动和C++程序使用的库联接,所以通常用g++来完成链接,为了统一起见,干脆编译/链接

Linux-0.11内核源码分析系列:关于线性地址,逻辑地址,物理地址的关系与区别

/* *Author : DavidLin *Date : 2014-11-22pm *Email : [email protected] or [email protected] *world : the city of SZ, in China *Ver : 000.000.001 *history : editor time do * 1)LinPeng 2014-11-22 created this file! * 2) */     以下所有描述基于Linux0.11内核及其所编写的年

HashMap和ConcurrentHashMap的区别,HashMap的底层源码。

Hashmap本质是数组加链表.根据key取得hash值,然后计算出数组下标,如果多个key对应到同一个下标,就用链表串起来,新插入的在前面. ConcurrentHashMap:在hashMap的基础上,ConcurrentHashMap将数据分为多个segment,默认16个(concurrency level),然后每次操作对一个segment加锁,避免多线程锁的几率,提高并发效率. 一.HashMap概述 HashMap基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允

java中break和continue的区别详解(附源码)

序言 在自己学习java语言的过程中,很容易把break和continue的用法混淆.为了便于以后快速查阅及温习,在此特留学习笔记一份. 简述 在任何迭代语句的主体部分,都可以用break和continue控制循环的流程.其中,break用于强行退出循环,不执行循环中剩余的语句.而continue则停止执行当前迭代,然后退回循环起始处,开始下一次迭代. 源码 下面这个程序向大家展示了break和continue在for和while循环中的例子: package com.mufeng.thefou

Java之局部内部类和匿名内部类的区别详解(附源码)

前言 前面提到过,可以在代码块里创建内部类,典型的方式是在一个方法体里面创建.局部内部类不能有访问说明符,因为它不是外围类的一部分:但是他可以访问当前代码块内的常量,以及此外围类的所有成员.下面的例子对局部内部类与匿名内部类的创建进行了比较. 示例源码 package com.mufeng.thetenthchapter; interface Counter { int next(); } public class LocalInnerClass { private int count = 0;

内核基础---AT&T汇编与x86汇编的区别

1.深入Linux内核的前提 因为以前学习过intel的x86汇编语言,所以本文就不在讲述汇编的基本语法了: 内核绝大部分的代码都是用C和汇编语言实现的,要理解内核,C语言大部分的人都已经掌握了,接下来就得首先掌握汇编知识,以便深入理解Linux内核知识!!! 2.学习Linux内核的线路 首先内核有基础部分和深入的部分,我认为应该从一个全局的角度去解读Linux内核,以便我们达到一个更加深刻的认识,从内核的整体架构--->内核源码的解读,并且在这个的过程中不断的去修改代码,编程调试是至关重要的

从Java源码的角度来分析HashMap与HashTable的区别

由于HashMap与HashTable都是用来存储Key-Value的键值对,所以经常拿来对比二者的区别,下面就从源码的角度来分析一下HashMap与HashTable的区别, 首先介绍一下两者的区别,然后再从源码分析. HahMap与HahTable两者主要区别: 1.继承的父类不同 <span style="font-size:18px;">public class HashMap<K, V> extends AbstractMap<K, V>

《Intel汇编第5版》 Intel CPU小端序

一.MASM汇编器中的数据类型 二.Intel汇编中的立即数类型 三.定义有符号和无符号整数 四.小端序 内存中数据按照字节存储,一个4个字节无符号整数,其高位存储在低地址上,低位存储在高地址上. 比如0x12345678这个整数,在内存中按照内存地址从小往大排列是:0X78 0x56 0x34 0x12 五.汇编代码验证 INCLUDE Irvine32.inc includelib Irvine32.lib includelib kernel32.lib includelib user32.