AT&T内联汇编示例

来源:互联网 发布:资金趋势指标公式源码 编辑:程序博客网 时间:2024/05/21 15:00


一、AT&T 内联汇编的语法格式

1、寄存器的引用方式

引用寄存器要在寄存器号前面加% 《==》intel汇编的引用寄存器前是不加% 的

例如:  mov %eax, %ebx


2、操作数的顺序

操作数排列是从源(左)到目的(右),

例如: mov %eax, %ebx   ==>将寄存器eax内的数据拷贝到寄存器ebx

<==>intel会汇编的引用顺序是从右到左的,和这个相反


3、常数、立即数的格式

使用立即数,要在立即数前面加$符号,例如, mov $1,%eax  =>给寄存器eax赋值1

使用常数,  mov  value, %eax  =>将常数value代表的数值赋值给寄存器eax

                    mov  $value, %eax =>将保存常数value的内存地址赋值给寄存器eax


4、指令都是小写字母


5、绝对转移和调用指令(jmp/call)的操作数前要加上“*”作为前缀

6、远程指令转移和远程调用指令为ljmp 和 lcall

     例如:

     ljmp $section,$offset;

     lcall $section,$offset;

7、远程返回指令  

    lret $stack_adjust;

8、寻址方式

    格式: disp(base,index,scale)  ==>  disp+base+index*scale

    例如:

    movl -4(%ebx), %eax   ==>  将  -4+%ebx 赋值给寄存器eax

    movl array(,%ebx,4),%eax  ==>  将  array+%ebx*4赋值给寄存器eax

    movl array(%ecx,%ebx,4),%eax  ==>将 array+%ecx+%ebx*4赋值给寄存器eax

9、内嵌汇编格式

      __asm__("section1;\n\t"    //注意,前后分别有两个--

                       "section2;\n\t"

                       "section3;\n\t"

                        :"=寄存器限定符"(变量名)   // 输出

                        :"寄存器限定符"(变量名)     //输入

                        :破坏描述部分

                        );


实例:

int main()
{
    int a1=10;
    int b1=0;
    __asm__ ("movl %1,%%eax;\n\t"     //汇编语句1,将后面限定描述部分的第1个参数(从0开始的),

                                                            // 也就是输入的b寄存器,赋值给寄存器eax
          "movl %%eax,%%ecx;"        // 注意,内嵌汇编中的寄存器前的%一定要用两个,因此GCC会在编译时去掉一个
        :"=a"(b1)                    //第0个限定描述,=表示这是个输出,a表示寄存器eax(b表示ebx,c表示ecx,d表示edx)
        :"b"(a1));                    //第1个限定描述,不带=表示它是个输入

                                          // S表示寄存器esi   ,D表示edi,r表示任何寄存器,“0”表示和前面那个限定用同一个寄存器


    printf("b1=%d",b1);
    return 0;
}

0 0
原创粉丝点击