⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 996.html

📁 著名的linux英雄站点的文档打包
💻 HTML
📖 第 1 页 / 共 3 页
字号:
                        <input maxlength=100 size=30 name=keyword2>
                      </div>
                    </td>
                  </tr></tbody> 
                </table>
              </form>
            </TD>
            <TD rowSpan=2><IMG src="images/header_r1_c7.gif" tppabs="http://www.linuxhero.com/docs/images/header_r1_c7.gif" width=26 border=0 name=header_r1_c7></TD>
          <TD><IMG height=83 src="images/spacer.gif" tppabs="http://www.linuxhero.com/docs/images/spacer.gif" width=1 border=0></TD></TR>
        <TR>
          <TD background="images/bgline.gif" tppabs="http://www.linuxhero.com/docs/images/bgline.gif"><IMG height=22 
            src="images/header_r2_c1.gif" tppabs="http://www.linuxhero.com/docs/images/header_r2_c1.gif" width=296 border=0 
            name=header_r2_c1></TD>
          <TD background="images/bgline.gif" tppabs="http://www.linuxhero.com/docs/images/bgline.gif" colSpan=5>
              <DIV align=right><FONT class=normalfont>当前位置: 
              <A href="index.html" tppabs="http://www.linuxhero.com/docs/index.html">本站首页</A>
              <font color="#FF6699">&gt;&gt;</font>
<A href="type14.html" tppabs="http://www.linuxhero.com/docs/type14.html">编程技术</A>                 | <A href="copyright.html" tppabs="http://www.linuxhero.com/docs/copyright.html">版权说明</A></font></DIV>
            </TD>
          <TD><IMG height=22 src="images/spacer.gif" tppabs="http://www.linuxhero.com/docs/images/spacer.gif" width=1 
        border=0></TD></TR></TBODY></TABLE>
      <TABLE cellSpacing=10 cellPadding=0 width="100%" bgColor=#ffffff 
        border=0>
         <TR>
          <TD>
            <TABLE cellSpacing=0 cellPadding=3 width="100%" border=0>
              
              <TR>
                <TD vAlign=top align=middle width="60%">
                  <TABLE cellSpacing=0 cellPadding=0 width="100%" 
                  background="images/back.gif" tppabs="http://www.linuxhero.com/docs/images/back.gif" border=0>
                    <TBODY>
                    <TR>
                        <TD vAlign=top width="80%"> 
                          <DIV align=center>
                        <FORM action="search.html" tppabs="http://www.linuxhero.com/docs/search.html" method=get>
                            </FORM>
                        <TABLE cellSpacing=0 cellPadding=0 width="95%" 
                          border=0><TBODY>
                          <TR>
                            <TD background="images/bgi.gif" tppabs="http://www.linuxhero.com/docs/images/bgi.gif" 
                          height=30></TD></TR></TBODY></TABLE>
                        <TABLE cellSpacing=0 cellPadding=3 width="95%" 
                        align=center border=0>
                          <TBODY>
                          <TR>
                            <TD>
                              <TABLE cellSpacing=0 cellPadding=3 width="100%" 
                              border=0>
                                <TBODY>
                                <TR>
                                      <TD vAlign=top> 
<p><FONT class=normalfont><B><font color=blue>AT&T/x86/asm语法</font></B></FONT><BR><FONT class=smallfont color=#ff9900>2004-04-23 15:18 pm</FONT><BR><FONT class=normalfont>作者:e4gle(e4gle@whitecell.org)<br>来自:Linux知识宝库<br>联系方式:无名<br><br>Homepage:http://www.whitecell.org<br>
<br>
DJGPP使用AT&T格式的汇编语法,和一般的intel格式的语法有点不同。主要不同点如下:<br>
<br>
AT&T语法颠倒了源和目的操作数的位置, 目的操作数在源操作数之后。寄存器操作数要有个%的前缀,立即数操作数要有个$符号的前缀。存储器操作数的大小取决于操作码的最后一个字符。 它们是b(8-bit), w(16-bit)和l(32-bit)。<br>
这里有一些例子。左边部分是at&t格式,右边是intel指令格式。<br>
movw %bx, %ax// mov ax, bx<br>
xorl %eax, %eax// xor eax, eax<br>
movw $1, %ax// mov ax,1<br>
movb X, %ah// mov ah, byte ptr X<br>
movw X, %ax// mov ax, word ptr X<br>
movl X, %eax// mov eax, X<br>
大部分操作指令,at&t和intel都是差不多的,除了这些:<br>
movsSD // movsx<br>
movzSD // movz<br>
<br>
S和D分辨代表源和目的操作数后缀。<br>
movswl %ax, %ecx// movsx ecx, ax<br>
cbtw        // cbw<br>
cwtl        // cwde<br>
cwtd        // cwd<br>
cltd        // cdq<br>
lcall $S,$O // call far S:O<br>
ljmp $S,$O  // jump far S:O<br>
lret $V     // ret far V<br>
操作嘛,前缀不能与它们作用的指令写在同一行。例如rep和stosd应该是两个相互独立的指令, 存储器的情况也有一点不同。通常intel格式的如下:<br>
<br>
section:[base + index*scale + disp]<br>
<br>
被写成:<br>
<br>
section:disp(base, index, scale)<br>
<br>
这里有些例子:<br>
<br>
movl 4(%ebp), %eax            // mov eax, [ebp+4])<br>
addl (%eax,%eax,4), %ecx      // add ecx, [eax + eax*4])<br>
movb $4, %fs:(%eax)           // mov fs:eax, 4)<br>
movl _array(,%eax,4), %eax    // mov eax, [4*eax + array])<br>
movw _array(%ebx,%eax,4), %cx// mov cx, [ebx + 4*eax + array])<br>
<br>
Jump 指令通常是个短跳转。可是, 下面这些指令都是只能在一个字节的范围内跳转: jcxz,jecxz,loop,loopz,loope,loopnz和loopne。象在线文档所说的那样,一个jcxz foo可以扩展成以下工作:<br>
jcxz cx_zero<br>
jmp cx_nonzero<br>
cx_zero:<br>
jmp foo<br>
cx_nonzero:<br>
文档也注意到了mul和imul指令。 扩展的乘法指令只用一个操作数,例如, imul $ebx, $ebx将不会把结果放入edx:eax。使用imul %ebx中的单操作数来获得扩展结果。<br>
<br>
<br>
--------------------------------------------------------------------------------<br>
<br>
Inline Asm<br>
我将首先开始inline asm, 因为似乎关于这方面的疑问非常多。这是最基本的语法了, 就象在线帮助信息<br>
中描述的:<br>
__asm__(asm statements : outputs : inputs : registers-modified);<br>
<br>
这四个字段的含义是:<br>
<br>
asm statements - AT&T 的结构, 每新行都是分开的。<br>
outputs - 修饰符一定要用引号引起来, 用逗号分隔<br>
inputs - 修饰符一定要用引号引起来, 用逗号分隔<br>
registers-modified - 名字用逗号分隔<br>
一个小小的例子:<br>
__asm__("<br>
pushl %eax<br>
movl $1, %eax<br>
popl %eax"<br>
);<br>
假如你不用到特别的输入输出变量或者修改任何寄存器的值,一般来说是不会使用到其他的三个字段的,让我们来分析一下输入变量。<br>
<br>
int i = 0;<br>
<br>
__asm__("<br>
pushl %%eax<br>
movl %0, %%eax<br>
addl $1, %%eax<br>
movl %%eax, %0<br>
popl %%eax"<br>
:<br>
: "g" (i)<br>
);// increment i<br>
不要为上面的代码所困扰! 我将尽力来解释它。我们想让输入变量i加1,没有任何输出变量, 也没有改变寄存器值(我们保存了eax值)。 因此,第二个和最后一个字段是空的。 因为指定了输入字段, 我们仍需要保留一个空的输出字段, 但是没有最后一个字段, 因为它没被使用。在两个空冒号之间留下一个新行或者至少一个空格。<br>
<br>
下面让我们来看看输入字段。 附加描述符可以修正指令来让你给定的编译器来正确处理这些变量。他们一般被附上双引号。 那么这个"g"是用来做什么的呢? 只要是合法的汇编指令,"g"就让编译器决定该在哪里加载i的值。一般来说,你的大部分输入变量都可以被赋予"g", 让编译器决定如何去加载它们 (gcc甚至可以优化它们!)。 其他描述符使用"r" (加载到任何可用的寄存器去), "a" (ax/eax), "b"(bx/ebx), "c" (cx/ecx), "d" (dx/edx), "D" (di/edi), "S" (si/esi), 等等。<br>
<br>
我们将要提到一个在asm代码里面的如%0的输入变量。如果我们有两个输入, 他们会一个是%0,一个是%1,在输入段里按顺序排列 (如下一个例子)。假如N个输入变量且没有输出变量, 从%0到%N-1将和输入字段里的变量相对应, 按顺序排列。<br>
<br>
如果任何的输入, 输出, 寄存器修改字段被使用, 汇编代码里的寄存器名必须用两个%来代替一个%。对应于第一个没有使用最后三个字段的例子。<br>
<br>
让我们看看两个输入变量且引入了"volatile"的例子:<br>
<br>
int i=0, j=1;<br>
__asm__ __volatile__("<br>
pushl %%eax<br>
movl %0, %%eax<br>
addl %1, %%eax<br>
movl %%eax, %0<br>
popl %%eax"<br>
:<br>
: "g" (i), "g" (j)<br>
);// increment i by j<br>
Okay, 现在我们已经有了两个输入变量了。没问题了, 我们只需要记住%0对应第一个输入变量(在这个例子中是i), %1对应在i后面的列出的j。<br>
Oh yeah, 这个volatile到底是什么意思呢? 它防止你的编译器修改你的汇编代码,就是不进行优化(纪录, 删除, 结合,等等优化手段。), 不改变代码原样来汇编它们。建议一般情况下使用volatile选项。<br>
<br>
让我们来看看输出字段:<br>
<br>
int i=0;<br>
__asm__ __volatile__("<br>
pushl %%eax<br>
movl $1, %%eax<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -