`

AT&T汇编指令

 
阅读更多

转自 http://ted.is-programmer.com/posts/5262.html

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 语言的字符串。

分享到:
评论

相关推荐

    AT&T汇编指令精简介绍

    好不容易找了一篇稍全面又简洁的指令集介绍 add,mov(bwl),test,sub,shr,cmp,lea,je,jne,ja,jb 列出来帮助搜索

    AT&T 汇编指令说明

    根据提供的文件信息,本文将重点解析与AT&T汇编指令相关的知识内容,特别是这些指令在Linux平台下的应用。 ### AT&T汇编指令简介 AT&T汇编语言是一种用于编写低级程序的语言,它广泛应用于包括Linux在内的多种Unix...

    AT&T汇编语言使用手册

    ### AT&T汇编语言使用手册知识点详解 #### 一、前言 《AT&T汇编语言使用手册》是一本详尽介绍了AT&T汇编语言及其语法的手册,它由Sun Microsystems公司出版,版权日期为1998年。该手册不仅涵盖了基本的汇编指令集...

    AT&T汇编语言与GCC内嵌汇编简介.pdf

    - 在AT&T汇编指令中,操作数扩展指令有两个后缀,一个指定源操作数的字长,另一个指定目标操作数的字长。AT&T的符号扩展指令为“movs”,零扩展指令为“movz”。因此,“movsbl %al, %edx”表示对寄存器`al`中的字节...

    AT&T汇编(linux汇编)

    AT&T汇编语法和Intel汇编在指令格式上有显著区别。在AT&T汇编中,操作数的顺序通常为“目的地”在前,“源”在后,而Intel汇编则相反。例如,`mov`指令在AT&T语法中写为`mov dst, src`,而在Intel语法中则是`mov ...

    AT&T汇编语言手册2015

    AT&T汇编语言手册2015是一本专注于x86架构汇编语言的重要参考资料,尤其对于那些寻求最新知识的开发者和技术爱好者来说,这是一份不可多得的资源。AT&T汇编语言与Intel汇编语言有所不同,其语法和指令表示方式有其...

    AT&T汇编语言手册2005老版本

    AT&T汇编语言手册2005版是学习和理解X86架构汇编编程的重要资源,尤其对于那些对早期计算机系统和低级编程感兴趣的读者来说。这份文档详细阐述了AT&T汇编语法,它是UNIX系统中常用的汇编语言风格。AT&T汇编与Intel...

    at&t专业汇编语言-Richard Blum.pdf

    从描述来看,本书的内容覆盖了两个主要方面:首先是AT&T汇编语言的基础编写过程,其次是详细解读了每一条汇编指令的含义。对于熟悉Linux和VxWorks平台的读者而言,这本书将有助于他们深入理解这些平台的底层工作原理...

    AT&T汇编伪指令

    在Linux环境下使用AT&T汇编语言时,每条汇编指令或伪指令通常遵循以下格式: ``` [:][}@comment [:][}@注释 ``` 这里的关键点在于标号的使用方式以及注释的处理。Linux ARM汇编中,标号并不一定要位于行首,只要以...

    at汇编语法讲解_汇编AT_at&t汇编_Vc_at&t汇编教程_

    本文将深入探讨AT&T汇编语法的核心概念、特点以及与Intel汇编的差异,并提供一些基本的使用指导。** **1. AT&T 汇编语法基础** AT&T汇编语法与Intel汇编语法的主要区别在于指令格式和寄存器表示方式。在AT&T语法中...

    AT&T汇编语言与gcc内嵌汇编简介

    AT&T汇编指令操作码的最后一个字母通常表示操作数的大小,如“b”代表字节,“w”代表字,“l”代表长字。这种后缀在INTEL汇编中也有类似的概念,如`BYTE PTR`、`WORD PTR`、`DWORD PTR`。 ### GCC内嵌汇编 GCC...

    AT&T汇编语言与GCC内嵌汇编简介[定义].pdf

    * 指令后缀:AT&T 汇编语言的指令操作码的最后一个字母表示操作数大小,例如“b” 表示 byte、“w” 表示 word、“l” 表示 long。 2. GCC 内嵌汇编 GCC 内嵌汇编是指在高级语言中嵌入汇编语言的代码,以提高程序...

    AT&T汇编语言教程

    3. **指令集**:AT&T汇编语言支持x86指令集,包括基本的算术逻辑指令、数据传送指令、控制转移指令等。 4. **兼容性**:AT&T汇编语言与大多数x86处理器兼容,适用于编写高效的操作系统内核代码、设备驱动程序等底层...

    AT&T汇编语言与GCC内嵌汇编简介

    ### AT&T汇编语言与GCC内嵌汇编简介 #### 1. AT&T与INTEL的汇编语言语法的区别 AT&T汇编语言与INTEL汇编语言在语法上存在一定的差异,这些差异主要体现在以下几个方面: ##### 1.1 大小写 - **INTEL格式**:指令...

    AT & T汇编语言

    - **指令格式**:AT&T汇编语言中的指令格式与Intel汇编不同,操作数顺序通常是目标操作数在前,源操作数在后,如`add $1, %eax`表示将立即数1加到寄存器`%eax`中。 - **内存引用**:在AT&T汇编语言中,内存地址通常...

    at&t汇编教程1

    AT&T汇编语言,通常用于Unix和类Unix系统,如Linux,它与Intel的x86汇编语言有所不同,主要在指令格式和语法上存在差异。本教程为英文原版,适合对汇编语言有基础了解或想要深入学习的开发者阅读。 AT&T汇编语言的...

    AT&T汇编语法总结

    通过以上六个方面的介绍,我们可以看到AT&T汇编语法在寄存器引用、操作数顺序、立即数和符号常数引用、操作数长度标注、以及符号扩展和零扩展指令上具有明确的语法规则。这些规则虽然可能与Intel语法有所区别,但...

    AT&T汇编语言和GCC内嵌汇编

    ### AT&T汇编语言与GCC内嵌汇编详解 #### 一、AT&T汇编语言简介 AT&T汇编语言是一种广泛应用于Unix及其衍生系统(包括Linux)中的汇编语言格式。它最初是为了适应Unix系统在不同硬件平台上的移植而发展起来的。...

    AT&T汇编语言

    AT&T汇编指令的后缀用于指示操作数的大小,如“b”代表字节,“w”代表字,“l”代表长字。同时,AT&T汇编支持操作数扩展指令,通过不同的后缀来指定源和目标操作数的字长,这与INTEL汇编中的“movsx”和“movzx”...

    AT&T汇编资料打包

    - **指令格式**:AT&T汇编中的指令通常以操作码和操作数的形式表示,操作数可以是立即数、寄存器、内存地址或符号。 - **寻址模式**:AT&T汇编有多种寻址方式,如直接寻址、间接寻址、基址加偏移量寻址等,这些寻址...

Global site tag (gtag.js) - Google Analytics