AT&T语法

来源:互联网 发布:xperia xzs知乎 编辑:程序博客网 时间:2024/06/05 14:12

1、立即数前面要加字符'$',寄存器操作数名前要加百分号'%',绝对跳转/调用(相对于与程序计数器有关的跳转/调用)操作数前面要加星号'*'。Intel语法没有这些限制;


2、AT&T语法与Intel语法使用的源和目的操作数的次序正好相反。AT&T的源和目的操作数是从左到右‘源,目的’。如:Intel语句‘add eax, 4',对应AT&T语句'addl $4, %eax’;


3、AT&T语法中内存操作数的长度(宽度)由操作码最后一个字符来确定。操作码后缀'b'、‘w'、’l'和’q‘分别指示内存引用宽度为8字节(byte)、16字节(word)、32字节(long)和64字节(qword)。Intel语法则通过在内存操作数前使用前缀'byte ptr'、‘word ptr'、'dword ptr'和'qword ptr'来达到相同目的。如:Intel语句’mov al, byte ptr foo‘,对应AT&T语句’movb $foo, %al';


4、AT&T语法中立即形式的远跳转和远调用为'ljmp/lcall $section, $offset',而Intel的是'jmp/call far section:offset'。同样AT&T语法中远返回指令‘lret $stack-adjust’对应Intel的'ret far stack-adjust';


5、AT&T汇编器不提供对多代码段程序的支持,UNIX类操作系统要求所有代码在一个段中;


6、Intel语法的间接内存引用形式:section:[base + index*scale + disp],对应于如下AT&T语法形式:section:disp(base, index, scale)。其中base和index是可选的32位基寄存器和索引寄存器;disp是可选的偏移值;scale是比例因子,取值范围是1、2、4和8,scale乘以索引index用来计算操作数地址。如果没有指定scale,则scale取默认值1。section为内存操作数指定可选的段寄存器,并且会覆盖操作数使用的当前默认段寄存器。请注意,如果指定的段覆盖寄存器与默认操作的段寄存器相同,则as就不会为汇编的指令再输出相同的段前缀。


7、JMP是无条件跳转指令,并可分为直接(direct)跳转和间接(indirect)跳转两类,而条件跳转指令只有直接跳转的形式。对于直接跳转指令,跳转到的目标指令的地址是作为跳转指令的一部分直接编码进跳转指令中;对于间接跳转指令,跳转的目的位置取自某个寄存器或某个内存位置中。直接跳转语句的写法是给出跳转目标处的标号;间接跳转语句的写法是必须使用一个星字符"*"作为操作指示符的前缀字符,并且该操作指示符使用与movl指令相同的语法。下面是直接和间接跳转的几个例子。

jmp NewLoc # 直接跳转。无条件直接跳转到标号NewLoc处继续执行。

jmp *%eax  # 间接跳转。寄存器%eax的值是跳转的目标位置。

jmp *(%eax)   # 间接跳转。从%eax指明的地址处读取跳转的目标位置。


8、常用寄存器加载代码说明

代码

说明

代码

说明

a

使用寄存器eax

m

使用内存地址

b

使用寄存器ebx

o

使用内存地址并可以加偏移值

c

使用寄存器ecx

I

使用常数0-31

d

使用寄存器edx

J

使用常数0-63

S

使用esi

K

使用常数0-255

D

使用edi

L

使用常数0-65535

q

使用动态分配字节可寻址寄存器(eax、ebx、ecx或edx)

M

使用常数0-3

r

使用任意动态分配的寄存器

N

使用1字节常数(0-255)

g

使用通用有效的地址即可(eax、ebx、ecx、edx或内存变量)

O

使用常数0-31

A

使用eax与edx联合(64位)

=

输出操作数。输出值将替换前值

+

表示操作数可读可写

&

早期会变的(earlyclobber)操作数。表示在使用完操作数之前,内容会被修改


9、Intel CPU 采用了所有函数必须遵守的寄存器用法统一惯例。该惯例指明,寄存器eax、edx和ecx的内容必须由调用者自己负责保存。当函数B被A调用时,函数B可以在不用保存这些寄存器内容的情况下任意使用它们而不会毁坏函数A所需要的任何数据。另外,寄存器ebx、esi和edi的内容则必须由被调用者B来保护。当被调用者需要使用这些寄存器中的任意一个时,必须首先在栈中保存其内容,并在退出时恢复这些寄存器的内容。因为调用者A(或者一些更高层的函数)并不负责保存这些寄存器内容,但可能在以后的操作中还需要用到原先的值。还有寄存器ebp和esp也必须遵守第二个惯例用法。

0 0
原创粉丝点击