随笔-内联汇编
GCC 内联汇编 HOWTO https://linux.cn/article-7688-1.html
https://www.cnblogs.com/sewain/p/14707347.html
x86汇编语言基础(AT&T语法) - 玩转Linux内核的文章 - 知乎 https://zhuanlan.zhihu.com/p/627238135
__asm__ __volatile__
(
"mov %1, %%rbx\n\t" // dest值传入rbx
"mov %2, %%rcx\n\t" // src传入rcx
"VAGE_LOOP:\n\t" // 循环开始
"mov (%%rbx), %%r8\n\t" // load 源地址数据到 r8
"mov %%r8, (%%rcx)\n\t" // r8 store 到目标地址
"add $8, %%rbx\n\t" // 源地址向后加8字节
"add $8, %%rcx\n\t" // 目标地址向后加8字节
"sub $8, %0\n\t" // size 减8字节
"jne VAGE_LOOP\n\t" // size 不为0向上跳转至循环开始处
:"=r"(size)
:"r"(dest),"r"(src),"0"(size)
:"rbx","rcx","r8"
);
使用的是AT&T语法,mov S,D,和intel汇编风格正好相反
"0"(size) 这里0是什么意思,因为size同时是输出参数,序号是从输出参数开始编号,所以size是%0,然后依次dest、src、size,size已经是输出参数了,所以用对应的输出参数作为下标
"rbx","rcx","r8" 定义被修改的寄存器,rbx、rcx 和 r8 在汇编代码中被修改,需要在输出列表中声明
+++
使用编号还是麻烦,容易出错,还有另一个更方便的操作:扩展 asm 格式还允许给这些占位符重命名,也就是给每一个寄存器起一个别名,然后在内联汇编代码中使用别名来操作寄存器。
__asm__ __volatile__
(
"mov %[v1], %%rbx\n\t"
"mov %[v2], %%rcx\n\t"
"VAGE_LOOP:\n\t"
"mov (%%rbx), %%r8\n\t"
"mov %%r8, (%%rcx)\n\t"
"add $8, %%rbx\n\t"
"add $8, %%rcx\n\t"
"sub $8, %[v3]\n\t"
"jne VAGE_LOOP\n\t"
: [v3]"=r"(size)
: [v1]"r"(dest),[v2]"r"(src),"[v3]"(size)
: "rbx","rcx","r8"
);
"[v3]"(size) 不写或者写成 "r"(size) 都是错误的写法
本文来自博客园,作者:LiYanbin,转载请注明原文链接:https://www.cnblogs.com/stellar-liyanbin/p/18397158