AT&T x86 asm语法

DJGPP 使用AT&T格式的汇编语法。和一般的intel格式的语法有点不同。主要不同点如下:

AT&T 语法颠倒了源和目的操作数的位置, 目的操作数在源操作数之后。寄存器操作数要有个%的前缀, 立即数操作数要有个$符号的前缀。 存储器操作数的大小取决于操作码的最后一个字符。 它们是b (8-bit), w (16-bit), 和 l (32-bit).

这里有一些例子。 左边部分是intel指令格式,右边是at&t格式。

movw %bx, %ax // mov ax, bx
xorl %eax, %eax // xor eax, eax
movw $1, %ax // mov ax,1
moVB X, %ah // mov ah, byte ptr X
movw X, %ax // mov ax, word ptr X
movl X, %eax // mov eax, X

大部分操作指令,at%t和intel都是差不多的,除了这些:

movsSD // movsx
movzSD // movz

S和D分辨代表源和目的操作数后缀。

movswl %ax, %ecx // movsx ecx, ax
cbtw // cbw
cwtl // cwde
cwtd // cwd
cltd // cdq
lcall $S,$O // call far S:O
ljmp $S,$O // jump far S:O
lret $V // ret far V

操作嘛前缀不能与他们作用的指令写在同一行。 例如, rep 和stosd应该是两个相互独立的指令, 存储器的情况也有一点不同。通常intel格式的如下:

section:[base + index*scale + disp]

被写成:

section:disp(base, index, scale)

这里有些例子:

movl 4(%ebp), %eax // mov eax, [ebp+4])
addl (%eax,%eax,4), %ecx // add ecx, [eax + eax*4])
movb $4, %fs:(%eax) // mov fs:eax, 4)
movl _array(,%eax,4), %eax // mov eax, [4*eax + array])
movw _array(%ebx,%eax,4), %cx // mov cx, [ebx + 4*eax + array])

Jump 指令通常是个短跳转。 可是, 下面这些指令都是只能在一个字节的范围内跳转: jcxz, jecxz, loop, loopz, loope, loopnz 和loopne。象在线文档所说的那样,一个jcxz foo可以扩展成以下工作:

jcxz cx_zero
jmp cx_nonzero
cx_zero:
jmp foo
cx_nonzero:

文档也注意到了mul和imul指令。 扩展的乘法指令只用一个操作数,例如, imul $ebx, $ebx将不会把结果放入edx:eax。使用imul %ebx中的单操作数来获得扩展结果。

Inline Asm

我将首先开始inline asm, 因为似乎关于这方面的疑问非常多。这是最基本的语法了, 就象在线帮助信息中描述的:

__asm__(asm statements : outputs : inputs : reGISters-modified);

这四个字段的含义是:

asm statements - AT&T 的结构, 每新行都是分开的。
outputs - 修饰符一定要用引号引起来, 用逗号分隔
inputs - 修饰符一定要用引号引起来, 用逗号分隔
registers-modified - 名字用逗号分隔
一个小小的例子:
__asm__("
pushl %eax\n
movl $1, %eax\n
popl %eax"
);

假如你不用到特别的输入输出变量或者修改任何寄存器的值,一般来说是不会使用到其他的三个字段的,

让我们来分析一下输入变量。

int i = 0;
__asm__("
pushl %%eax\n
movl %0, %%eax\n
addl $1, %%eax\n
movl %%eax, %0\n
popl %%eax"
:
: "g" (i)
); // increment i

不要为上面的代码所困扰! 我将尽力来解释它。我们想让输入变量i加1,我们没有任何输出变量, 也没有改变寄存器值(我们保存了eax值)。 因此,第二个和最后一个字段是空的。 因为指定了输入字段, 我们仍需要保留一个空的输出字段, 但是没有最后一个字段, 因为它没被使用。在两个空冒号之间留下一个新行或者至少一个空格。

时间: 2024-10-27 23:27:24

AT&T x86 asm语法的相关文章

《逆向工程权威指南》目录—导读

版权 逆向工程权威指南 • 著 [乌克兰] Dennis Yurichev 译 Archer 安天安全研究与应急处理中心 责任编辑 陈冀康 • 人民邮电出版社出版发行 北京市丰台区成寿寺路11号 邮编 100164 电子邮件 315@ptpress.com.cn 网址 http://www.ptpress.com.cn • 读者服务热线:(010)81055410 反盗版热线:(010)81055315 版权声明 逆向工程权威指南 Simplified Chinese translation c

疑犯追踪:谁是Mirai蠕虫的幕后黑手?

本文讲的是疑犯追踪:谁是Mirai蠕虫的幕后黑手?,在2016年的9月22日,我的网站因为遭受Mirai蠕虫病毒的攻击而瘫痪了4天,该病毒会将不安全的物联网设备感染为自己的僵尸网络的一部分,然后再对外发起更多的感染攻击.在这之后的一个礼拜,发动这次攻击的幕后黑手化名为"Anna-Senpai"对外发布了Mirai的源代码. 经过几个月的深入挖掘,KrebsOnSecurity已经发现了Anna-Senpai的真实身份,还有帮他开发和修改该恶意软件的同谋的身份.下图为Anna-Senpa

请别再拿“String s = new String("xyz");创建了多少个String实例”来面试了吧

这帖是用来回复高级语言虚拟机圈子里的一个问题,一道Java笔试题的. 本来因为见得太多已经吐槽无力,但这次实在忍不住了就又爆发了一把.写得太长干脆单独开了一帖. 顺带广告:对JVM感兴趣的同学们同志们请多多支持高级语言虚拟机圈子  以下是回复内容.文中的"楼主"是针对原问题帖而言. =============================================================== 楼主是看各种宝典了么--以后我面试人的时候就要专找宝典答案是错的来问,方便筛人

C++ 100款开源界面库 (10)

(声明:Alberl以后说到开源库,一般都是指著名的.或者不著名但维护至少3年以上的.那些把代码一扔就没下文的,Alberl不称之为开源库,只称为开源代码.这里并不是贬低,像Alberl前面那个系列的教程<2013 duilib入门简明教程>,还有本系列教程,还有前面介绍的CodeProject,基本上都是代码往上面一扔,就不用再怎么维护的.这些都称之为开源代码,其实开源代码对新手的帮助更大,因为很简明的说明了代码用法~O(∩_∩)O~)       前面两个教程已经对制作界面的几种方式进行了

SourceInsight

    为什么要用Source Insight呢?貌似是因为比完整的IDE要更快一些,比较利于查看大量的代码. 软件的安装很简单,设置好安装目录. 配置好文档路径,当然这个也可以在Options里面改,选Options->Preferences-里面的Folders标签就行. Project的建立和工作区域 在菜单中选择Project->New Project-可以建立新的工程,自定义工程名,选择保存路径,然后新建. 新建确定之后,在接下来的菜单中,需要选择Project Source Dir

FlasCC例子研究之hellointerop

例子中的注释已经很详细了,我觉得逐行翻译一下,就完全可以体现出此例子的意义 #include <stdio.h>  #include <string.h>  #include "AS3/AS3.h"  //<-----大家注意这货,它提供了C++中调用AS3的方法 int main(int argc, char **argv)  {     /*        flascc使用GCC的inline asm语法来使你可以在C++编写和调用AS3代码.    

Spinlock编程

在 Linux Kernel 里有著许多重要的资料结构,这些资料在操作系统的运作中扮演著举足轻重的角色.然而,Linux 是个多工的操作系统,也就是在同一时间里可以同时有许多的行程在执行,所以,很有可能某个行程在依序读取 inode list,同时却又有另一个在 inode list 里加入新的 inode,这会造成什么情形呢?这会造成 inode list 的不稳定.所以,在 Kernel 里,我们需要一个机制,可以使得当我们在修改某个重要的资料结构时,不能被中断,即使被中断了,这个资料结构由

C语言ASM汇编内嵌语法【转】

转自:http://www.cnblogs.com/latifrons/archive/2009/09/17/1568198.html GCC 支持在C/C++代码中嵌入汇编代码,这些汇编代码被称作GCC Inline ASM--GCC内联汇编.这是一个非常有用的功能,有利于我们将一些C/C++语法无法表达的指令直接潜入C/C++代码中,另外也允许我们直接写 C/C++代码中使用汇编编写简洁高效的代码. 1.基本内联汇编 GCC中基本的内联汇编非常易懂,我们先来看两个简单的例子: __asm__

探索ORACLE之ASM概念(完整版)_oracle

一.     ASM(自动存储管理)的来由: ASM是Oracle 10g R2中为了简化Oracle数据库的管理而推出来的一项新功能,这是Oracle自己提供的卷管理器,主要用于替代操作系统所提供的LVM,它不仅支持单实例,同时对RAC的支持也是非常好.ASM可以自动管理磁盘组并提供有效的数据冗余功能.使用ASM(自动存储管理)后,数据库管理员不再需要对ORACLE中成千上万的数据文件进行管理和分类,从而简化了DBA的工作量,可以使得工作效率大大提高. 二.     什么是ASM ASM它提供