用户操作
[即时聊天] [发私信] [加为好友]
KendivID:Kendiv
402220次访问,排名126好友0人,关注者2
Kendiv的文章
原创 155 篇
翻译 42 篇
转载 71 篇
评论 219 篇
Kendiv的公告
我们家最坏的就是他~~ 我的mimi,可爱吧~~
2008.08.22
Coding Life
/*---------------------
Personal Info:
Name: Kendiv
----------------------*/
最近评论
bluehouse1985:Linux 环境下的多核调试
— Intel + Totalview 强强联合!
目前,在软件开发行业,各种性能优异的调试工具层出不穷。但是,它们中的绝大部分都只支持windows环境。即使能支持linux平台,操作起来也很不方便。因此,对于长期在linux上编写程序的开发人员来说,如何调试就成了一个令人头痛的问题!Intel软件 和 Total……
ruanjian311:受益匪浅
AloneSword:我喜欢 你家的 那个最坏的。
wanttocto:谢谢兄弟!!!
可以发一份中英文都有的给我吗?
xiao_17_xiao@126.com
centsky:大受启发,谢谢楼主!
文章分类
收藏
相册
AI
智能中国
AntiVirus
Malware-Research‏
AV Engine
a tool to collect malware
ClamAV for Windows
ClamAV Virus Database
ClamAV-Home
Disassembly Challenges
Filetype Detection - wiki
IceSword - Home
OpenAnti-Virus
BBS、论坛
Juniper Networks
Visual Studio Team System - 微软中文技术社区
ChinaUnix Blog
飞翔,嵌入式linux
Data Loss Prevention (DLP) Security
Hacker
Collection.Sites
Z0MBiE's HomePage
ICAP
ICAP-Forum
POSIX Threads(PThreads)
Open Source POSIX Threads for Win32
Squid
squid-home
Virtualization
虚拟机之家
Web Tech.
Https - wiki
ICP - Home
技术网站
absurd,大牛
ChinaUnix
Cisco Systems
CSDN
DDK MVP Expert Zone
Dr. Dobb's Journal
Ethereal
Kernel Mustard的专栏
Linux Journal
LinuxAid 技术支持中心
Microsoft Systems Journal
Microsoft TechNet
MSDN 技术资源库
MSDN中文WebCast
SysInternals(FreeWare)
The Code Project
VCHelp
VC在线
VC知识库
Windows Driver Programming(WD-3)
ZDNet China
中国协议分析网
哈工大·纯C论坛
安全焦点
微软中国社区
绿盟技术版
罗云彬的编程乐园
驱动开发网
其他
前程无忧
数字北京
清韵书院
铁血军事网
铁血读书
网上书店
China-Pub
第二书店
友情链接
JoyCode博客堂
Rong
嵌入式软件开发网(UCSDN)
狗狗
邹欣的Blog
存档
订阅我的博客
XML聚合  FeedSky

转载 AT&T x86 asm 语法收藏

新一篇: GCC精彩之旅 | 旧一篇: SSL/TLS/WTLS原理

AT&T x86 asm 语法

创建时间:2001-04-09
文章属性:翻译
文章提交:e4gle (e4gle_at_hackermail.com)

AT&T x86 asm 语法
译:el8<el8@m4in.org>,alert7<alert7@m4in.org>
          from m4in security teams(www.m4in.org)

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值)。

因此,第二个和最后一个字段是空的。 因为指定了输入字段, 我们仍需要保留一个空的输出字段, 但是没有最后一个字段, 因为它没被使用

。在两个空冒号之间留下一个新行或者至少一个空格。

下面让我们来看看输入字段。 附加描述符可以修正指令来让你给定的编译器来正确处理这些变量。他们一般被附上双引号。那么这个"g"是用

来做什么的呢?  只要是合法的汇编指令,"g"就让编译器决定该在哪里加载i的值。一般来说,你的大部分输入变量都可以被赋予 "g", 让编

译器决定如何去加载它们 (gcc甚至可以优化它们!)。 其他描述符使用"r" (加载到任何可用的寄存器去), "a" (ax/eax), "b" (bx/ebx),

"c" (cx/ecx), "d" (dx/edx), "D" (di/edi), "S" (si/esi), 等等。

我们将要提到一个在asm代码里面的如%0的输入变量。如果我们有两个输入, 他们会一个是%0一个是%1, 在输入段里按顺序排列 (如下一个例

子)。假如N个输入变量且没有输出变量, 从%0 到%N-1将和输入字段里的变量相对应, 按顺序排列。

如果任何的输入, 输出, 寄存器修改字段被使用, 汇编代码里的寄存器名必须用两个%来代替一个%。对应于第一个没有使用最后三个字段的例

子。

让我们看看两个输入变量且引入了"volatile"的例子:

    int i=0, j=1;
    __asm__ __volatile__("
        pushl %%eax\n
        movl %0, %%eax\n
        addl %1, %%eax\n
        movl %%eax, %0\n
        popl %%eax"
    :
    : "g" (i), "g" (j)
    );    // increment i by j
Okay, 现在我们已经有了两个输入变量了。没问题了, 我们只需要记住%0对应第一个输入变量(在这个例子中是i), %1对应在i后面的列出的j


Oh yeah, 这个volatile到底是什么意思呢? 它防止你的编译器修改你的汇编代码,就是不进行优化(纪录, 删除, 结合,等等优化手段。), 不

改变代码原样来汇编它们。建议一般情况下使用volatile选项。

让我们来看看输出字段:

    int i=0;
    __asm__ __volatile__("
        pushl %%eax\n
        movl $1, %%eax\n
        movl %%eax, %0\n
        popl %%eax"
    : "=g" (i)
    );    // assign 1 to i
这看起来非常象我们前面提到的输入字段的例子; 确实也没有很大的不同。所有的输出修饰符前面都应该加上=字符,他们同样在汇编代码里

面用%0到%N-1来表示, 在输出字段按顺序排列。你一定会问如果同时有输入和输出字段会怎么排序的呢? 好,下面一个例子就是让大家知道

如何同时处理输入输出字段的。
    int i=0, j=1, k=0;
    __asm__ __volatile__("
        pushl %%eax\n
        movl %1, %%eax\n
        addl %2, %%eax\n
        movl %%eax, %0\n
        popl %%eax"
    : "=g" (k)
    : "g" (i), "g" (j)
    );    // k = i + j
Okay, 唯一个不清楚的地方就是汇编代码中的变量的个数。我马上来解释一下。
当同时使用输入字段和输出字段的时候:

%0 ... %K 是输出变量

%K+1 ... %N 是输入变量

在我们的例子中, %0 对应k, %1 对应i, %2对应j。很简单,是吧?

到现在为止我们都没有使用最后一个字段(registers-modified)。如果我们要在我们的汇编代码里使用任何寄存器, 我们要明确的用push和

pop指令来保存它们, 或者列到最后一个字段里面让gcc来处理它们。

这是前面的一个例子, 没有明确的保留和存贮eax。

    int i=0, j=1, k=0;
    __asm__ __volatile__("
        pushl %%eax\n    /*译者注:好像原文说的有点问题,明明是保存了eax的值,:(*/
        movl %1, %%eax\n
        addl %2, %%eax\n
        movl %%eax, %0\n
        popl %%eax"
    : "=g" (k)
    : "g" (i), "g" (j)
    : "ax", "memory"
    );    // k = i + j
我们让gcc来保存和存贮eax, 如果必要的话。一个16-bit寄存器名代表了32-, 16-或8-bit寄存器。 如果我们要改写内存 (写入一个变量等。

), 建议在register-modified字段里面来指定"memroy"修饰符。这意味着除了第一个例子我们都应该加上这个修饰符, 但是直到现在我才提出

来, 是为了更简单易懂。

在你的内联汇编里面定位标号应该使用b或f来作为终止符, 尤其是向后向前的跳转。(译者注:b代表向后跳转,f代表向前跳转)

For example,

    __asm__ __volatile__("
        0:\n
            ...
            jmp 0b\n
            ...
            jmp 1f\n
            ...
        1:\n
            ...
    );
这里有个用c代码和内联汇编代码混合写的跳转程序的例子(thanks to Srikanth B.R for this tip).

void MyFunction( int x, int y )
{
    __asm__( "Start:" );
    __asm__( ...do some comparison... );
    __asm__( "jl Label_1" );

    CallFunction( &x, &y );    
    __asm__("jmp Start");

Label_1:
    return;
}

--------------------------------------------------------------------------------

External Asm
Blah... Okay fine. Here's a clue: Get some of your C/C++ files, 且用gcc -S file.c来编译。 然后查看file.S文件。基本结构如下:
    .file "myasm.S"

    .data
    somedata: .word 0
    ...

    .text
    .globl __myasmfunc
    __myasmfunc:
    ...
    ret
Macros, macros! 头文件libc/asmdefs.h便于你写asm。 在你的汇编代码最前面包含此头文件然后就可以使用宏了。一个例子: myasm.S:
    #include <libc/asmdefs.h>

    .file "myasm.S"

    .data
    .align 2
    somedata: .word  0
    ...

    .text
    .align 4
    FUNC(__MyExternalAsmFunc)
    ENTER
            movl   ARG1, %eax
            ...
            jmp    mylabel
            ...
        mylabel:
            ...
    LEAVE
这是一个好的纯粹的汇编代码框架。

发表于 @ 2006年04月23日 01:28:00|评论(loading...)|编辑

新一篇: GCC精彩之旅 | 旧一篇: SSL/TLS/WTLS原理

评论

#hacker47 发表于2006-04-23 17:26:00  IP: 218.23.65.*
交个朋友吧,两个共同爱好:
猫咪,编程。
#EDC 发表于2006-04-23 17:46:00  IP: 221.226.214.*
胡锦涛主席说:“我也每天使用微软公司的操作系统”

胡主席访问微软时说:“比尔·盖茨先生是中国的朋友,我则是微软的朋友。”他告诉盖茨:“我也每天使用微软公司的操作系统。”盖茨则说:“无论何时您需要关于windows的建议,我将很高兴提供帮助。”如果不考虑中美贸易摩擦的大背景,这番对话简直就是一对老朋友之间的对话,而不是国家首脑和一位企业领导者之间的对话。

---------------------------------------------------------

胡锦涛主席访问微软重申保护知识产权决心
2006.04.21 来自:国际金融报 

  表示加强知识产权保护不仅对中国扩大对外开放和改善投资环境十分必要,而且对于加强中国自主创新能力也是不可或缺的。

  美国西雅图消息当地时间4月18日下午,正在美国华盛顿州西雅图访问的中国国家主席胡锦涛,会见了华盛顿州州长葛瑞格尔。

  随后,胡锦涛主席前往设在莱德蒙德的微软公司总部参观,并出席了在比尔·盖茨家举行的欢迎宴会。

  参观微软是胡锦涛此次访美行程中极其重要的一个环节。在参观了微软公司的主要技术后,胡锦涛重申了中国加强知识产权保护的决心。他表示,此举“不仅对中国扩大对外开放和改善投资环境”十分必要,而且“对于加强中国自主创新能力”也是不可或缺的。

  胡锦涛称赞了比尔·盖茨在微软取得的成就,并说:“因为你,比尔·盖茨先生是中国的朋友,我则是微软的朋友。”他表示希望看到微软和中国的合作,并欢迎微软将来增加在中国的投资。

  就在胡锦涛开始访美的当天,联想与微软签订12亿美元的软件购买协议,此前方正、同方及TCL等公司也签订了价值17亿美元的软件购买协议,为其生产的计算机预装微软Windows操作系统,以此抵制盗版软件。

  微软公司的高管们认为,胡锦涛的这次访问象征着中国政府对知识产权的态度出现根本转变。中国已开始强化在知识产权问题上的立场,因为加强对知识产权的保护符合中国自身的经济发展利益。

  微软首席技术官克瑞格·蒙迪表示,“我认为,一年多来,中国领导人已越过了一道坎,意识到知识产权对中国本身的未来要求也至关重要。”尽管问题不会在一夜之间改变,但他认为最近的几则通告是一种“重大飞跃”。

  蒙迪说,中国仍是微软优先考虑的重点,无论是作为一个市场还是未来市场的技术来源,尽管在知识产权方面存在一些困难。

  当天上午10时50分左右,胡锦涛乘坐的专机抵达西雅图佩因机场。在机场发表书面讲话时,胡锦涛指出,中美都是伟大的国家,拥有广泛的共同利益和坚实的合作基础,肩负着促进世界和平与发展的共同责任。一个健康稳定、不断发展的中美关系不仅造福两国人民,而且有利于亚太地区及世界的和平、稳定、繁荣。

  当晚在比尔·盖茨豪宅为胡主席一行举行的欢迎宴会上,美中关系全国委员会主席欧伦斯对胡锦涛此行给予了高度评价。他称,“胡锦涛把访美的第一站放在西雅图,其实是用行动对解决中美贸易争端作出承诺——中国愿意开放经济、同美国加强合作。这就是一个‘负责任的利益相关者’所代表的含义。”

  据悉,胡锦涛将于当地时间19日参观波音公司,然后飞往华盛顿与布什总统在白宫举行会谈,鉴于
#hongmy525 发表于2007-04-11 19:55:22  IP: 222.88.22.*
好文章
发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © Kendiv