at&t汇编语言
2008-03-07 11:31
260 查看
编辑
GAS中每个操作都是有一个字符的后缀,表明操作数的大小。
注意:GAL使用后缀“l”同时表示4字节整数和8字节双精度浮点数,这不会产生歧义因为浮点数使用的是完全不同的指令和寄存器。
操作数格式:
注:M[xx]表示在存储器中xx地址的值,R[xx]表示寄存器xx的值,这种表示方法将寄存器、内存都看出一个大数组的形式。
数据传送指令:
注:均假设栈往低地址扩展。
算数和逻辑操作地址:
特殊算术操作:
注:64位数通常存储为,高32位放在edx,低32位放在eax。
条件码:
条件码寄存器描述了最近的算数或逻辑操作的属性。
CF:进位标志,最高位产生了进位,可用于检查无符号数溢出。
OF:溢出标志,二进制补码溢出——正溢出或负溢出。
ZF:零标志,结果为0。
SF:符号标志,操作结果为负。
比较指令:
访问条件码指令:
跳转指令:
转移控制指令:(函数调用):
用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表示输入的参数,从前往后统一编号(如上例中*dest表示%0,reset是%1,x是%2,y是%3),”r”表示整数寄存器,”=”表示对其进行了赋值。%eax要写成%%eax,这是c语言字符串的规则,别忘了code-string就是一个c语言的字符串。
GAS中每个操作都是有一个字符的后缀,表明操作数的大小。
[align=center]C声明[/align] | [align=center]GAS后缀[/align] | [align=center]大小(字节)[/align] |
[align=center]char[/align] | [align=center]b[/align] | [align=center]1[/align] |
[align=center]short[/align] | [align=center]w[/align] | [align=center]2[/align] |
[align=center](unsigned) int / long / char* [/align] | [align=center]l[/align] | [align=center]4[/align] |
[align=center]float[/align] | [align=center]s[/align] | [align=center]4[/align] |
[align=center]double[/align] | [align=center]l[/align] | [align=center]8[/align] |
[align=center]long double[/align] | [align=center]t[/align] | [align=center]10/12[/align] |
操作数格式:
[align=center]格式[/align] | [align=center]操作数值[/align] | [align=center]名称[/align] | [align=center]样例(GAS = C语言)[/align] |
[align=center]$Imm[/align] | [align=center]Imm[/align] | [align=center]立即数寻址[/align] | [align=center]$1 = 1[/align] |
[align=center]Ea[/align] | [align=center]R[Ea][/align] | [align=center]寄存器寻址[/align] | [align=center]%eax = eax[/align] |
[align=center]Imm[/align] | [align=center]M[Imm][/align] | [align=center]绝对寻址[/align] | [align=center]0x104 = *0x104[/align] |
[align=center](Ea)[/align] | [align=center]M[R[Ea]][/align] | [align=center]间接寻址[/align] | [align=center](%eax)= *eax[/align] |
[align=center]Imm(Ea)[/align] | [align=center]M[Imm+R[Ea]][/align] | [align=center](基址+偏移量)寻址[/align] | [align=center]4(%eax) = *(4+eax)[/align] |
[align=center](Ea,Eb)[/align] | [align=center]M[R[Ea]+R[Eb]][/align] | [align=center]变址[/align] | [align=center](%eax,%ebx) = *(eax+ebx)[/align] |
[align=center]Imm(Ea,Eb)[/align] | [align=center]M[Imm+R[Ea]+R[Eb]][/align] | [align=center]寻址[/align] | [align=center]9(%eax,%ebx)= *(9+eax+ebx)[/align] |
[align=center](,Ea,s)[/align] | [align=center]M[R[Ea]*s][/align] | [align=center]伸缩化变址寻址[/align] | [align=center](,%eax,4)= *(eax*4)[/align] |
[align=center]Imm(,Ea,s)[/align] | [align=center]M[Imm+R[Ea]*s][/align] | [align=center]伸缩化变址寻址[/align] | [align=center]0xfc(,%eax,4)= *(0xfc+eax*4)[/align] |
[align=center](Ea,Eb,s)[/align] | [align=center]M(R[Ea]+R[Eb]*s)[/align] | [align=center]伸缩化变址寻址[/align] | [align=center](%eax,%ebx,4) = *(eax+ebx*4)[/align] |
[align=center]Imm(Ea,Eb,s)[/align] | [align=center]M(Imm+R[Ea]+R[Eb]*s)[/align] | [align=center]伸缩化变址寻址[/align] | [align=center]8(%eax,%ebx,4) = *(8+eax+ebx*4)[/align] |
数据传送指令:
指令 | 效果 | 描述 |
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; | 无符号除法,保存余数和商 |
条件码:
条件码寄存器描述了最近的算数或逻辑操作的属性。
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 |
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表示输入的参数,从前往后统一编号(如上例中*dest表示%0,reset是%1,x是%2,y是%3),”r”表示整数寄存器,”=”表示对其进行了赋值。%eax要写成%%eax,这是c语言字符串的规则,别忘了code-string就是一个c语言的字符串。
相关文章推荐
- AT&T汇编语言及其寻址方式简述
- 『转载』__asm__ __volatile__ GCC的内嵌汇编语法 AT&amp;T汇编语言语法
- __asm__ __volatile__ GCC的内嵌汇编语法 AT&T汇编语言语法
- AT&T汇编语言——工具及程序组成
- AT&T汇编语言——简单实例及工具演示
- AT&T汇编语言与GCC内嵌汇编简介
- Linux 汇编语言开发指南 Intel 格式--AT&T 格式
- Linux 汇编语言开发指南(AT&T)
- AT&T与Intel汇编语言的比较
- __asm__ __volatile__ GCC的内嵌汇编语法 AT&T汇编语言语法
- Linux Debugging(二): 熟悉AT&T汇编语言
- __asm__ __volatile__ GCC的内嵌汇编语法 AT&T汇编语言语法(一)
- __asm__ __volatile__ GCC的内嵌汇编语法 AT&T汇编语言语法
- AT&amp;amp;T汇编语言笔记
- __asm__ __volatile__ GCC的内嵌汇编语法 AT&T汇编语言语法(一)
- AT&T汇编语言与GCC内嵌汇编简介
- linux下的C语言开发(AT&T 汇编语言)
- GCC的内嵌汇编语法 AT&T汇编语言语法
- linux下的C语言开发(AT&T 汇编语言)
- AT&T汇编语言与GCC内嵌汇编,Linux内核数据结构之链表