GCC内联汇编(1)Get started

GCC内联汇编(1)Get started

  • 作者:柳大·Poechant(钟超)
  • 邮箱:zhongchao.ustc#gmail.com(# -> @)
  • 博客:Blog.CSDN.net/Poechant
  • 日期:July 7th, 2012

1. Intel vs. AT&T

其实并不是要说 Intel 和 AT&T PK 的故事,哈哈。因为首先要熟悉 Intel syntax 的汇编指令写法和 AT&T syntax 汇编指令的写法,所以看下表:


+------------------------------+------------------------------------+
|       Intel Code             |      AT&T Code                     |
+------------------------------+------------------------------------+
| mov     eax,1                |  movl    $1,%eax                   |   
| mov     ebx,0ffh             |  movl    $0xff,%ebx                |   
| int     80h                  |  int     $0x80                     |   
| mov     ebx, eax             |  movl    %eax, %ebx                |
| mov     eax,[ecx]            |  movl    (%ecx),%eax               |
| mov     eax,[ebx+3]          |  movl    3(%ebx),%eax              | 
| mov     eax,[ebx+20h]        |  movl    0x20(%ebx),%eax           |
| add     eax,[ebx+ecx*2h]     |  addl    (%ebx,%ecx,0x2),%eax      |
| lea     eax,[ebx+ecx]        |  leal    (%ebx,%ecx),%eax          |
| sub     eax,[ebx+ecx*4h-20h] |  subl    -0x20(%ebx,%ecx,0x4),%eax |
+------------------------------+------------------------------------+

2. 示例

看一个用内联汇编写的例子,计算两数的和:


#include <stdio.h>                                                                                                                                                                                   
int main(void) {

    int foo = 10, bar = 15;

    __asm__ __volatile__ (
        "addl   %%ebx, %%eax"
        :"=a"(foo)
        :"a"(foo), "b"(bar)
        :"%eax"
    );

    printf("foo + bar = %d\n", foo);

    return 0;
}

该程序作如下解释:

  • __asm__用于表示这是一个内联汇编代码段;
  • 如果使用了__volatile修饰符,则这段内联汇编代码不会被编译器优化掉,但是如果只是做简单的计算,不会产生任何可能的 side effects,则最好不要加这个修饰符,这样可以使编译器帮助我们优化代码;
  • "=a"(foo)"表示这段内联汇编代码运行结束后,输出结果放在寄存器%eax中,然后%eax中的内容再放到fooC变量中;
  • "a"(foo)表示这段内联汇编代码开始运行时,fooC变量输入到%eax寄存器中,多个输入值可以用上面示例中的方式表达。
  • 以冒号开始的那两行,其实都是“约束”,这个是constraint的直译,其实你可以理解为边界条件,即输入输出条件。
  • 最后一个冒号开始的行,是告诉编译器,哪些寄存器的值会在内联汇编代码的运行过程中被篡改,因此不要使用这些寄存器去保存值。这里就是%eax的值会被篡改的意思。

3. 寄存器缩写

+---+--------------------+
| r |    Register(s)     |
+---+--------------------+
| a |   %eax, %ax, %al   |
| b |   %ebx, %bx, %bl   |
| c |   %ecx, %cx, %cl   |
| d |   %edx, %dx, %dl   |
| S |   %esi, %si        |
| D |   %edi, %di        |
+---+--------------------+

Reference

  1. http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html

-

转载请注明来自柳大的CSDN博客:Blog.CSDN.net/Poechant

-

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值