您的位置:首页 > 其它

AT&T汇编指令

2011-03-29 22:07 323 查看
GAS
中每个操作都是有一个字符的后缀,表明操作数的大小。

C
声明

GAS
后缀

大小
(
字节
)

char

b

1

short

w

2

(unsigned) int / long / char*

l

4

float

s

4

double

l

8

long double

t

10/12

注意:
GAL
使用后缀“
l
”同时表示
4
字节整数和
8
字节双精度浮点数,这不会产生歧义因为浮点数使用的是完全不同的指令和寄存器。

操作数格式:


格式

操作数值

名称

样例(
GAS = C
语言)

$Imm

Imm

立即数寻址

$1 = 1

Ea

R[Ea]

寄存器寻址

%
eax = eax

Imm

M[Imm]

绝对寻址

0x104 = *0x104


Ea


M[R[Ea]]

间接寻址


%eax

= *eax

Imm(Ea)

M[Imm+R[Ea]]

(
基址
+
偏移量
)
寻址

4(%eax) = *(4+eax)


Ea,Eb


M[R[Ea]+R[Eb]]

变址

(%eax,%ebx) = *(eax+ebx)

Imm

Ea,Eb


M[Imm+R[Ea]+R[Eb]]

寻址

9(%eax,%ebx)= *(9+eax+ebx)

(,Ea,s)

M[R[Ea]*s]

伸缩化变址寻址

(,%eax,4)= *(eax*4)

Imm(,Ea,s)

M[Imm+R[Ea]*s]

伸缩化变址寻址

0xfc(,%eax,4)= *(0xfc+eax*4)

(Ea,Eb,s)

M(R[Ea]+R[Eb]*s)

伸缩化变址寻址

(%eax,%ebx,4) = *(eax+ebx*4)

Imm(Ea,Eb,s)

M(Imm+R[Ea]+R[Eb]*s)

伸缩化变址寻址

8(%eax,%ebx,4) = *(8+eax+ebx*4)

注:
M[xx]
表示在存储器中
xx
地址的值,
R[xx]
表示寄存器
xx
的值,这种表示方法将寄存器、内存都看出一个大数组的形式。

数据传送指令:


指令

效果

描述

movl S,D

D <-- S

传双字

movw S,D

D <-- S

传字

movb S,D

D <-- S

传字节

movsbl S,D

D <--
符号扩展
S

符号位填充
(
字节
->
双字
)

movzbl S,D

D <--
零扩展
S

零填充
(
字节
->
双字
)

pushl S

R[%esp] <-- R[%esp] – 4;

M[R[%esp]] <-- S

压栈

popl D

D <-- M[R[%esp]]


R[%esp] <-- R[%esp] + 4;

出栈

注:均假设栈往低地址扩展。

算数和逻辑操作地址:


指令

效果

描述

leal S,D

D = &S

movl
地版,
S
地址入
D

D
仅能是寄存器

incl D

D++


1

decl D

D--


1

negl D

D = -D

取负

notl D

D = ~D

取反

addl S,D

D = D + S



subl S,D

D = D – S



imull S,D

D = D*S



xorl S,D

D = D ^ S

异或

orl S,D

D = D | S



andl S,D

D = D & S



sall k,D

D = D << k

左移

shll k,D

D = D << k

左移
(

sall)

sarl k,D

D = D >> k

算数右移

shrl k,D

D = D >> k

逻辑右移

特殊算术操作:


指令

效果

描述

imull S

R[%edx]:R[%eax] = S * R[%eax]

无符号
64
位乘

mull S

R[%edx]:R[%eax] = S * R[%eax]

有符号
64
位乘

cltd S

R[%edx]:R[%eax] =
符号位扩展
R[%eax]

转换为
4
字节

idivl S

R[%edx] = R[%edx]:R[%eax] % S;

R[%eax] = R[%edx]:R[%eax] / S;

有符号除法,保存余数和商

divl S

R[%edx] = R[%edx]:R[%eax] % S;

R[%eax] = R[%edx]:R[%eax] / S;

无符号除法,保存余数和商

注:
64
位数通常存储为,高
32
位放在
edx
,低
32
位放在
eax


条件码:


条件码寄存器描述了最近的算数或逻辑操作的属性。

CF
:进位标志,最高位产生了进位,可用于检查无符号数溢出。

OF
:溢出标志,二进制补码溢出——正溢出或负溢出。

ZF
:零标志,结果为
0


SF
:符号标志,操作结果为负。

比较指令:


指令

基于

描述

cmpb S2,S1

S1 – S2

比较字节,差关系

testb S2,S1

S1 & S2

测试字节,与关系

cmpw S2,S1

S1 – S2

比较字,差关系

testw S2,S1

S1 & S2

测试字,与关系

cmpl S2,S1

S1 – S2

比较双字,差关系

testl S2,S1

S1 & S2

测试双字,与关系

访问条件码指令:


指令

同义名

效果

设置条件

sete D

setz

D = ZF

相等
/


setne D

setnz

D = ~ZF

不等
/
非零

sets D

D = SF

负数

setns D

D = ~SF

非负数

setg D

setnle

D = ~(SF ^OF) & ZF

大于(有符号
>


setge D

setnl

D = ~(SF ^OF)

小于等于
(
有符号
>=)

setl D

setnge

D = SF ^ OF

小于
(
有符号
<)

setle D

setng

D = (SF ^ OF) | ZF

小于等于
(
有符号
<=)

seta D

setnbe

D = ~CF & ~ZF

超过
(
无符号
>)

setae D

setnb

D = ~CF

超过或等于
(
无符号
>=)

setb D

setnae

D = CF

低于
(
无符号
<)

setbe D

setna

D = CF | ZF

低于或等于
(
无符号
<=)

跳转指令:


指令

同义名

跳转条件

描述

jmp Label

1

直接跳转

jmp *Operand

1

间接跳转

je Label

jz

ZF

等于
/


jne Label

jnz

~ZF

不等
/
非零

js Label

SF

负数

jnz Label

~SF

非负数

jg Label

jnle

~(SF^OF) & ~ZF

大于
(
有符号
>)

jge Label

jnl

~(SF ^ OF)

大于等于
(
有符号
>=)

jl Label

jnge

SF ^ OF

小于(有符号
<


jle Label

jng

(SF ^ OF) | ZF

小于等于
(
有符号
<=)

ja Label

jnbe

~CF & ~ZF

超过
(
无符号
>)

jae Label

jnb

~CF

超过或等于
(
无符号
>=)

jb Label

jnae

CF

低于
(
无符号
<)

jbe Label

jna

CF | ZF

低于或等于
(
无符号
<=)

转移控制指令:(函数调用):


指令

描述

call Label

过程调用,返回地址入栈,跳转到调用过程起始处,返回地址是
call
后面那条指令的地址

call *Operand

leave

为返回准备好栈,为
ret
准备好栈,主要是弹出函数内的栈使用及
%ebp


GCC


C

中潜入汇编代码:


asm( code-string [:output-list [ : input-list [ :overwrite-list]]]);

注意,后面的参数(如overwrite-list
)如果为空则不要相应的“:”,而如果前面参数(如output-list)为空则需要用“:”占位。

如:

asm ("..."

: //output需要占位

: "r" (src) //后面的Overwrites不能写,我测试的结果是写了编译不过

};

如:

Int ok_umul(unsigned x,unsigned y,unsigned *dest)

{

int result;

asm(“movl %2 , %%eax; mull %3; movl %%eax,%0;/

setae %dl; movzbl %%dl,%1”

: “=r” (*dest) , “=r” (result) //output

: “r” (x) , “r” (y) //inputs

: “%ebx” , “%edx” //Overwrites

);

return result;

}

我们用
%0--%n
表示输入的参数,
”r”
表示整数寄存器,
”=”
表示对其进行了赋值。
%eax
要写成
%%eax
,这是
c
语言字符串的规则,别忘了
code-string
就是一个
c
语言的字符串。

原:http://ted.is-programmer.com/posts/5262.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: