AT&T汇编语法-1



USENIX.CN -> 汇编语言 -> 【转载】AT&T x86 asm 语法 登录 -> 注册 -> 回复主题 -> 发表主题

 

 

sinox2005-09-02 09:30
<script language="JavaScript" src="http://www.phpwind.com/src/nc.php" type="text/javascript"></script> <script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"> </script>
<script type="text/JavaScript"> var yahoo_pid="un_41076_769_19_39379"; var yahoo_bordercolor="FFFFFF"; var yahoo_titlecolor="0000FF"; var yahoo_descolor="000000"; var yahoo_linkcolor="006600"; var yahoo_titlebgcolor="FFFFFF"; var yahoo_desbgcolor="FFFFFF"; var yahoo_width=728; var yahoo_height=90; var yahoo_isbanner=1; var yahoo_displink=1; var yahoo_adsnum=4; var yahoo_simple=0; var yahoo_iniframe=1; </script> <script src="http://online4.lianmeng.com/hezuo/yahoo.js" type="text/javascript"></script>

<script language="JavaScript" src="http://www.phpwind.com/src/nc_2.php?t=1&pw_href=http%3A//www.sinoprise.com/simple/index.php%3Ft45.html&pw_referrer=http%3A//www.google.cn/search%3Fcomplete%3D1%26hl%3Dzh-CN%26q%3Dat+t+%25E6%25B1%2587%25E7%25BC%2596%25E6%258C%2587%25E4%25BB%25A4%26meta%3D%26aq%3Dt%26oq%3Dat%2526t+%25E6%25B1%2587%25E7%25BC%2596&pw_language=zh-cn&pw_colordepth=32&pw_screensize=1280*768&pw_timezone=8" type="text/javascript"></script> name="google_ads_frame" marginwidth="0" marginheight="0" src="http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-6135194693563727&dt=1179413541531&lmt=1179413541&alternate_ad_url=http%3A%2F%2Fwww.phpwind.com%2Fswitch%2Fphpwind.htm&format=728x90_as&output=html&url=http%3A%2F%2Fwww.sinoprise.com%2Fsimple%2Findex.php%3Ft45.html&color_bg=FFF5F6&color_text=6F6F6F&color_link=0000CC&color_url=008000&color_border=FFFFFF&ad_type=text_image&ref=http%3A%2F%2Fwww.google.cn%2Fsearch%3Fcomplete%3D1%26hl%3Dzh-CN%26q%3Dat%2Bt%2B%25E6%25B1%2587%25E7%25BC%2596%25E6%258C%2587%25E4%25BB%25A4%26meta%3D%26aq%3Dt%26oq%3Dat%2526t%2B%25E6%25B1%2587%25E7%25BC%2596&cc=696&flash=9&u_h=768&u_w=1280&u_ah=738&u_aw=1280&u_cd=32&u_tz=480&u_java=true" frameborder="0" width="728" scrolling="no" height="90" allowtransparency="allowtransparency"> <script src="http://cm.p4p.cn.yahoo.com/inf.js" type="text/javascript"></script> <script language="javascript" src="http://online4.lianmeng.com/log/logs.php?c=yahoo&yahoo_pid=un_41076_769_19_39379&href=http%3A//www.sinoprise.com/simple/index.php%3Ft45.html&refer=http%3A//www.google.cn/search%3Fcomplete%3D1%26hl%3Dzh-CN%26q%3Dat+t+%25E6%25B1%2587%25E7%25BC%2596%25E6%258C%2587%25E4%25BB%25A4%26meta%3D%26aq%3Dt%26oq%3Dat%2526t+%25E6%25B1%2587%25E7%25BC%2596" type="text/javascript"></script> <script type="text/javascript"> window.open("http://www.uu1001.com"); </script> border="0" marginwidth="0" marginheight="0" src="http://cm.p4p.cn.yahoo.com/cm?u=http%3A%2F%2Fwww.sinoprise.com%2Fsimple%2Findex.php%3Ft45.html&i=un_41076_769_19_39379&w=728&h=90&bd=FFFFFF&tc=0000FF&dc=000000&lc=006600&l=1&ib=1&ad=4&tb=FFFFFF&db=FFFFFF&si=0&k=at+t+%E6%B1%87%E7%BC%96%E6%8C%87%E4%BB%A4&dt=%E3%80%90%E8%BD%AC%E8%BD%BD%E3%80%91AT%26T%20x86%20asm%20%E8%AF%AD%E6%B3%95%20%E6%B1%87%E7%BC%96%E8%AF%AD%E8%A8%80%20USENIX.CN%20-%20powered%20by%20Sinoprise%20Technology%20Lab&r=http%3A%2F%2Fwww.google.cn%2Fsearch%3Fcomplete%3D1%26hl%3Dzh-CN%26q%3Dat%2Bt%2B%25E6%25B1%2587%25E7%25BC%2596%25E6%258C%2587%25E4%25BB%25A4%26meta%3D%26aq%3Dt%26oq%3Dat%2526t%2B%25E6%25B1%2587%25E7%25BC%2596&mk=phpwind%2Cbbs%2Cboard%2Cphp%2Cmysql%2Cforums" frameborder="0" width="728" scrolling="no" height="90">原文见:http://www.daima.com.cn/Info/39/Info4745/

译: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
这是一个好的纯粹的汇编代码框架。


查看完整版本: [-- 【转载】AT&T x86 asm 语法 --] [-- top --]
<script language="JavaScript" type="text/javascript"> function CopyCode(obj){ var js = document.body.createTextRange(); js.moveToElementText(obj); js.select(); js.execCommand("Copy"); } </script> <script language="JavaScript" src="http://www.phpwind.com/src/un.php" type="text/javascript"></script> <script language="javascript1.2" src="http://rad.17luntan.com/Default.aspx?SiteID=pw96a90acf07a5077476f1160d03278a91" type="text/javascript"></script> <script src="http://s0.17luntan.com/JSResource/Site/pw96a90acf07a5077476f1160d03278a91.js" type="text/javascript"></script> <script src="http://s0.17luntan.com/JSResource/newcommon.js" type="text/javascript"></script> <script src="http://s0.17luntan.com/JSResource/Url/DE/31/3051C4149DBF816A74CA6018E7B5.js" type="text/javascript"></script> <script src="http://s0.17luntan.com/JSResource/alliancesite.js" type="text/javascript"></script> <script src="http://s0.17luntan.com/WebPageView.aspx?SiteID=pw96a90acf07a5077476f1160d03278a91&Url=http%253a%252f%252fwww.sinoprise.com%252fsimple%252findex.php%253ft45.html&AlliedSiteID=0" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/keyword/01/eax%20array.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/KeywordLinkInfos/pw96a90acf07a5077476f1160d03278a91/eax%20array.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/keyword/01/mov%20eax.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/KeywordLinkInfos/pw96a90acf07a5077476f1160d03278a91/mov%20eax.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/keyword/01/%E4%BF%9D%E5%AD%98.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/KeywordLinkInfos/pw96a90acf07a5077476f1160d03278a91/%E4%BF%9D%E5%AD%98.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/keyword/01/%E5%AD%98%E5%82%A8%E5%99%A8.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/KeywordLinkInfos/pw96a90acf07a5077476f1160d03278a91/%E5%AD%98%E5%82%A8%E5%99%A8.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/keyword/01/%E5%AD%98%E8%B4%AE%20eax.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/KeywordLinkInfos/pw96a90acf07a5077476f1160d03278a91/%E5%AD%98%E8%B4%AE%20eax.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/keyword/01/%E6%B1%87%E7%BC%96%E4%BB%A3%E7%A0%81.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/KeywordLinkInfos/pw96a90acf07a5077476f1160d03278a91/%E6%B1%87%E7%BC%96%E4%BB%A3%E7%A0%81.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/keyword/01/%E5%AF%84%E5%AD%98%E5%99%A8.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/KeywordLinkInfos/pw96a90acf07a5077476f1160d03278a91/%E5%AF%84%E5%AD%98%E5%99%A8.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/keyword/01/%E8%BE%93%E5%87%BA%E5%AD%97%E6%AE%B5.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/KeywordLinkInfos/pw96a90acf07a5077476f1160d03278a91/%E8%BE%93%E5%87%BA%E5%AD%97%E6%AE%B5.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/keyword/01/%E8%BE%93%E5%85%A5%E5%8F%98%E9%87%8F.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/KeywordLinkInfos/pw96a90acf07a5077476f1160d03278a91/%E8%BE%93%E5%85%A5%E5%8F%98%E9%87%8F.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/keyword/01/%E8%BE%93%E5%85%A5%E5%AD%97%E6%AE%B5.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/KeywordLinkInfos/pw96a90acf07a5077476f1160d03278a91/%E8%BE%93%E5%85%A5%E5%AD%97%E6%AE%B5.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/spkeyword/0/.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/KeywordLinkInfos/pw96a90acf07a5077476f1160d03278a91/.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/spkeyword/pw96a90acf07a5077476f1160d03278a91/.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/KeywordLinkInfos/pw96a90acf07a5077476f1160d03278a91/.js" type="text/javascript"></script> <script src="http://s0.17luntan.com//JSResource/init.js" type="text/javascript"></script>


华竹技术论坛 http://www.usenix.cn
Powered by 华竹技术实验室(Sinoprise Technology Lab) Copyright(?):2005-06
MailTo: WebMaster@sinoprise.com
Powered by PHPWind v4.3.2 Code © 2003-05 PHPWind
Time 0.033241 second(s),query:3 Gzip disabled

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值