gcc和clang使用intel格式的内联汇编

gcc和clang最新版本都支持-masm=intel可以将内部汇编格式切换成intel语法,此时内联汇编也是intel语法了。

https://www.cnblogs.com/litifeng/p/7864836.html

https://stackoverflow.com/questions/10990018/how-to-generate-assembly-code-with-clang-in-intel-syntax/23630416

还有一种方法是在内联汇编开头用.intel_syntax切换成intel格式,在内联汇编结尾用.att_syntax切换成at&t语法。不过这种方法由于gcc对于操作数的格式化风格并没有改变,还需要保留at&t语法的操作数前缀格式,比如%eax、$0x10、-0x10(%ebp)等,因此现在已不建议使用。

gcc的内联汇编的格式是asm("汇编文本":输出列表:输入列表:影响列表);。

【汇编文本】

汇编文本是一个字符串,每一行之间用\n\t隔开,\n是必需的,\t主要是为了生成的汇编文本好看。可以使用C语言的字符串拼接语法将这个字符串从C语言语法上分成若干行,但不能代替\n\t。

"mov eax,ebx\n\t"
"xor ebx,ebx\n\t"
// 相当于
"mov eax,ebx\n\txor ebx,ebx\n\t"

【输出列表/输入列表】

基本格式是【"约束表达式"(C语言表达式)】,汇编文本中按照先后顺序用%0 %1 %2...引用,先编号输出项,再编号输入项。

也可以使用这种格式【[汇编名称]"约束表达式"(C语言表达式)】,汇编文本中用%[汇编名称]引用,个人推荐使用这种格式。

寄存器例如可以用"a"(粗略指定al,ax,eax,rax)、"eax"(精确指定直接写寄存器名)、"r"(顺序分配)。

内存可以用"m"(一般用于变量),立即数用"i"(一般用于常量),寄存器/内存/立即数均可的话用"g"。

指定寄存器的话,gcc会在汇编代码之前将输入值存入寄存器中,并将汇编代码中对应项目替换为寄存器名称,汇编代码之后将寄存器值存入输出变量中。

指定内存的话,gcc会将汇编代码中对应项目替换为内存地址。

指定立即数的话,gcc会将汇编代码中对应项目替换为立即数。

还可以使用"0" "1" "2" ... "9"表示与项目0...9使用相同的汇编元素但C语言元素不同,比如指定输出寄存器和输入寄存器是同一个,但输入是一个C语言变量,输出是另一个C语言变量。

输出列表可以像"=a" "=eax" "=r" "=m" "=g"之类的一样添加输出前缀。比如"=m"表示仅输出,"+m"表示输入并输出,"=&a"表示a寄存器被该项独占,虽然不用于输入,但输入列表中的"r" "g"仍不得使用a寄存器。

输入列表可以添加"%"前缀,表示C语言表达式可以与后一个项目的C语言表达式互换。

【影响列表】

表示除输入输出列表外,汇编文本影响的其它内容。可以用"eax" "ebx"表示修改了这些寄存器的值,因此需要保护这些寄存器。另外"cc"表示影响了标志寄存器eflags,"memory"表示读/写了除输出列表/输入列表以外的变量的值,比如读/写了指针指向的值。

关于内联汇编格式的更多信息,可以参考这篇文章:http://www.nagain.com/activity/article/18/

也可以参考官方文档:https://gcc.gnu.org/onlinedocs/gcc/Using-Assembly-Language-with-C.html

下面是一个示例:

#include <stdio.h>

int main()
{
    int a = 3, b = 2;
    int quo = 0, rem = 0;
    asm("mov eax, %[a]\n\t"
        "cdq\n\t"
        "idiv %[b]\n\t"
        "mov %[quo], eax\n\t"
        "mov %[rem], edx\n\t"
        :[quo]"=m"(quo),[rem]"=m"(rem)
        :[a]"m"(a),[b]"m"(b)
        :"eax","edx","cc"
        );
    printf("result=%d,remainder=%d\n", quo, rem);
    return 0;
}

一个不好的消息,虽然gcc可以切换成intel语法,但是某些项目可能还是使用at&t语法。

如果需要了解at&t汇编格式可以参考:https://www.jianshu.com/p/0480e431f1d7

一个好消息,arm汇编没有at&t语法这种垃圾了。

发布了29 篇原创文章 · 获赞 1 · 访问量 3417

猜你喜欢

转载自blog.csdn.net/defrag257/article/details/102453714