AT&T的基本格式
- AT&T指令集中指令用的是小写字母,这一点上与intel指令集有所不同(intel指令集用的是大写字母)
- AT&T指令需要在立即数前加上$符号来说明这是一个立即数
- AT&T指令需要在寄存器前面加上%来说明这是一个寄存器
- AT&T指令源操作数在前,目的操作数在后
- AT&T指令的后缀:
b = byte (8 bit).
s = single (32-bit floating point).
w = word (16 bit).
l = long (32 bit integer or 64-bit floating point).
q = quad (64 bit).
t = ten bytes (80-bit floating point).
- AT&T指令未写明操作数长度时:
如果没有指定操作数长度的话,编译器将按照目标操作数的长度来设置.比如指令”
mov
%ax,%bx",由于目标操作数bx的长度为两个字节,那么编译器将把此指令等同于"movw%ax,
%bx".同样道理,指令“mov $4, %ebx”等同于指令“movl $4, %ebx",”push %al"等同于
“pushb %al".对于没有指定操作数长度,但编译器又无法猜测的指令,编译器将会报错, .
比如指令”push $4".
- AT&T指令的寻址操作:
用一个公式来总结表示x(y,m,n)
最终使用的地址为x+y+m*n
- AT&T指令的操作数
操作数有三种,一种是立即数,一种是寄存器,一种是内存地址(地址这种操作数需要去内存里找到对应的内容进行操作,lea操作比较特殊,把内存地址当做立即数来处理)
立即数:前面有$的数字
寄存器:寄存器(例如:eax,ebx。。。)地址:带()的表达式、前面无$的数字
上面介绍的是AT&T汇编大概的基本格式
接下来是具体的汇编命令
mov
mov 源操作数 目的操作数
作用:把源操作数的内容拷贝到到目的操作数对应的内容里去
注意:目的操作数不能为立即数;源操作数和目的操作数不能同时为地址
imull
imull(%esi,%edx,4),%eax
完成操作时eax=eax*(esi+edx4)
作用:目的操作数=源操作数目的操作数
call
call <函数名>
作用:调用函数,创建新的栈帧
add
add 源操作数 目的操作数
作用:目的操作数=源操作数+目的操作数
sub
sub 源操作数 目的操作数
作用:目的操作数=源操作数-目的操作数
ret
一般在调用函数结束时使用,继续执行原来的代码
call <函数名>
mov a b
以此为例,继续执行代码,执行mov a b
push
push %eax
将eax中四个字节的值压入到栈中,同时esp减4
作用:压栈
pop
pop %eax
将栈顶四个字节的内容弹给eax,同时esp加4
作用:弹栈
lea
类似于mov,但lea不会进行寻址操作,会将地址直接进行拷贝
即地址在lea使用中等同于立即数
test
test 源操作数 目的操作数
test不会改变两个操作数的任何东西,仅会将他们的内容进行与操作,然后根据结果设置标志位
cmp
cmp 源操作数 目的操作数
举个例子:cmp a b
如果 a=1,b=0,这行汇编相当于 b<a
如果 a=0,b=1,这行汇编相当于 b>a
如果 a=0,b=0,这行汇编相当于 b=a
作用:比较两个数,根据比较结果改变标志位
最后是常用的标志位。
CF:进位标志,无符号数溢出。
OF:溢出标志,二进制补码溢出(正溢出或负溢出)。
ZF:零标志,运算结果为0。
SF:符号标志,操作结果为负。