关于Linux AT&T Asm的零星小结

原创 2006年05月19日 00:17:00
本文作者:sodme
本文出处:http://blog.csdn.net/sodme
声明:本文可以不经作者同意任意转载、复制、传播,但任何对本文的引用均须保留本文的作者、出处及本行声明信息!谢谢!

前段时间作性能优化时, 研究过一段时间的linux AT&T asm, 一点体会写出来与大家共享.

我们知道linux的asm采用的是AT&T汇编语法, 关于它的详细文档在以下的地址可以获得:
http://asm.sourceforge.net/articles/linasm.html

看文档虽然是比较规矩的作法, 但对于诸如我等对未知世界好奇心过盛而又心急易上火的人类而言, 看代码要远来得轻松和契意:

#include <iostream>
int main(void)
{
    int result, input;
    input = 2;
    result = 3;
    __asm__
    (

    "movl %1, %0/n"
    "subl $1, %1/n"
    "movl %1, %0"
   
    : "=r"(result)
    : "m"(input)
    );
   
    std::cout << "result=" << result << std::endl;
    return 0;
}

形如以上形式, 加两个":", 是很多AT&T asm教程里都会说到的方法, 其作用在于规定输入输出参数, 而在汇编里会以%1和0%之类的来代替这些参数, 这样就实现了参数传递和计算结果的返回. 但是, 我一向比较少采用这种作法.

个人认为, 对于性能优化而言, gcc -O3选项所作的确实已经非常牛X了, 但对于不便采用-O3优化处理的, 手动优化还是有必要的. 而在手动优化这方面, 一般都会比较关注如何在C或C++里嵌入汇编, 直接使用汇编语言的方法写算法我觉得没必要而且编码时间较长也复杂. 所以, 一般我会这么干: 先用高级语言写出函数原型, 对于已有算法, 我会先gcc -S编译生成汇编代码, 然后在这个代码的基础之上再作优化. 这样作的另一个好处是, 对于参数和局部变量的地址引用可以通过分析编译后的汇编代码而轻易获得, 这样也方便我们在自己的汇编算法里来引用它们. 当然, 另外遇到的一种问题是, 可能有时我们会直接写汇编, 比如进行一些简单且快速运算之类的.

我所使用的内嵌汇编形式, 一般会直接这么写:

int func( int a, int b)
{
    ...
   
    __asm__
    (
       ...

        "movl $1, %eax/n"

       ...
    );

    ...
}

想把哪段代码进行优化, 就直接将那段代码用__asm__()的方式括起来, 但不用加":"的方式规定输入输出参数, 因为我觉得%1和%0这样的方式更象是机器所看的东西, 而不是人类应该看的, 人类最起码也要看个"以字母开头的, 字母和数字的集合"这样定义出来的东西. 我一般会使用经过对ebp修正的地址来间接寻址访问变量, 也就是一般情况下, 函数变量访问的最普通方式[ebp + xx].

为了有一个更加感性的认识, 下面再贴段AT&T asm代码:

.LFB1411:
    pushl    %ebp
.LCFI0:
    movl    %esp, %ebp
.LCFI1:
    subl    $4, %esp
.LCFI2:
    movl    %eax, -4(%ebp)
    movl    -4(%ebp), %eax
    movl    (%eax), %eax
    movl    %eax, %edx
    shrl    $31, %edx
    movl    -4(%ebp), %eax
    movl    (%eax), %eax
    shrl    $6, %eax
    xorl    %eax, %edx
    movl    -4(%ebp), %eax
    movl    (%eax), %eax
    shrl    $4, %eax
    xorl    %eax, %edx
    movl    -4(%ebp), %eax
    movl    (%eax), %eax
    shrl    $2, %eax
    xorl    %eax, %edx
    movl    -4(%ebp), %eax
    movl    (%eax), %eax
    shrl    %eax
    xorl    %eax, %edx
    movl    -4(%ebp), %eax
    movl    (%eax), %eax
    xorl    %edx, %eax
    andl    $1, %eax
    movl    %eax, %edx
    sall    $31, %edx
    movl    -4(%ebp), %eax
    movl    (%eax), %eax
    shrl    %eax
    orl    %eax, %edx
    movl    -4(%ebp), %eax
    movl    %edx, (%eax)
    leave
    ret

由这段代码来看AT&T asm与intel asm的不同点可能印象更深刻一些:
1.源操作数与目的操作数,在两种语法下截然相反, AT&T asm中, 左边的是源, 右边的是目的;
2.几乎所有的数据操作指令都会有intel asm指令字后加个l, 表示的是long;
3.立即数用$开头;
4.寄存器是以%开头;
5.间接寻址符号是"()", 而不是intel asm的"[]";

从形式上来看, 似乎两种语法的不同之处也就这么多. 但实际的应用中, 可能还存在很多的不一样, 比如:

intel asm下的:
mov ebx, dword ptr [LABLE_TEST]

到了AT&T asm下可能就不得不换成:

lea LABLE_TEST, %ebx
movl (%ebx), %ebx

(未完待续, 想起来再加)

AT&amp;T汇编格式

绝大多数 Linux 程序员以前只接触过DOS/Windows 下的汇编语言,这些汇编代码都是 Intel 风格的。但在 Unix 和 Linux 系统中,更多采用的还是 AT&T 格式,两者在语法格...
  • u011414997
  • u011414997
  • 2015年10月14日 22:46
  • 300

AT&amp;T汇编指令总结

http://blogold.chinaunix.net/u3/92010/showart_2083551.html1.寄存器引用     引用寄存器要在寄存器号前加百分号%,如“movl %eax...
  • ztguang
  • ztguang
  • 2016年03月30日 10:18
  • 332

linux下的C语言的asm内嵌式汇编

最近在上linux系统安全分析这门课,自己对这一方便比较感兴趣,就记载在这里。 关于asm内嵌式汇编 __asm__( " 汇编语句模板" : "输出部分 " : "输入部分 " ...
  • gaotangtiankai
  • gaotangtiankai
  • 2014年02月18日 15:49
  • 2454

Linux Study之--通过udev创建ASM DISK(RAC共享存储)

Linux Study之--通过udev创建ASM DISK(RAC共享存储) 系统环境:RedHat EL64 Oracle:   Oracle 11gR2    在Oracle ...
  • lqx0405
  • lqx0405
  • 2016年01月13日 17:14
  • 1389

【Linux学习笔记】Linux C中内联汇编的语法格式及使用方法(Inline Assembly in Linux C)

在阅读Linux内核源码或对代码做性能优化时,经常会有在C语言中嵌入一段汇编代码的需求,这种嵌入汇编在CS术语上叫做inline assembly。本文的笔记试图说明Inline Assembly的基...
  • slvher
  • slvher
  • 2013年04月28日 20:53
  • 10836

如何在项目中正确添加汇编代码

如何在项目中正确添加汇编代码 -- 张佩  1.      问题描述 在以往的编程经历中,本人最常使用的汇编代码是__asm {int 3}。它可以在我的代码中插入一个软件断...
  • cosmoslife
  • cosmoslife
  • 2013年06月10日 22:27
  • 712

Linux下的AT&amp;T语法(即GNU as 汇编语法)入门

http://blogold.chinaunix.net/u3/105209/showart_2085748.html学习这么长时间,一直在C语言这一层面上钻研和打拼,日积月累,很多关于C的疑惑在书本...
  • ztguang
  • ztguang
  • 2016年03月30日 10:18
  • 2072

搞定Linux下Oracle ASM的安装

Linux下安装Oracle RAC时,要弄asm,这东东很麻烦。要跟内核跑,Oracle Linux好点,光盘中自带就有了。不像其它要跑到Oracle官网去下载asmlib 。而且这个东东,步骤不少...
  • xcltapestry
  • xcltapestry
  • 2013年12月24日 23:28
  • 5562

Android漫游记(5)---ARM GCC 内联汇编烹饪书(附实例分析)

关于本文档 GNU C编译器针对ARM RISC处理器,提供了内联汇编支持。利用这一非常酷炫的特性,我们可以用来优化软件代码中的关键部分,或者可以使用针对特定处理的汇编处理指令。 ...
  • lifeshow
  • lifeshow
  • 2014年06月24日 17:43
  • 4160

从ARMASM汇编到GNU ARM ASM汇编

http://yaoguangle.blog.sohu.com/82624968.html 以前用ARM的IDE工具,使用的是ARM标准的汇编语言。现在要使用GNU的工具,当然要了解一...
  • ztguang
  • ztguang
  • 2016年02月01日 00:00
  • 218
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于Linux AT&amp;T Asm的零星小结
举报原因:
原因补充:

(最多只允许输入30个字)