概述
一言以蔽之, 用汇编模板表示函数实现,输出和输入表示参数,%0, %1 表示输出、输入所修饰部分的编号,同时描述C 参数与汇编寄存器的关系。
内嵌汇编语法如下:
_asm_ _volatile_ (
汇编语句模板:
输出部分:
输入部分:
破坏描述部分
)
下面通过一个简单的例子来熟悉内嵌汇编的语法规则。
max@ubuntu:~$ cat add.c
#include <stdio.h>
int main()
{
/* val1+val2=val3 */
unsigned int val1 = 1;
unsigned int val2 = 2;
unsigned int val3 = 0;
printf("val1:%d, val2:%d,val3:%dn", val1, val2, val3);
asm volatile(
"movl $0, %%eaxnt" /* clear %eax to 0*/
"addl %1, %%eaxnt" /* %eax += val1 */
"addl %2, %%eaxnt" /* %eax += val2 */
"movl %%eax, %0nt" /* val2 = %eax*/
: "=m" (val3) /* output =m mean only write output
memory variable*/
: "c" (val1), "d" (val2) /* input c or d %ecx/%edx*/
);
printf("val1:%d+val2:%d=val3:%dn", val1, val2,val3);
return 0;
}
max@ubuntu:~$
这个例子是用汇编代码实现val3 = val1 + val2 的功能,我们具体来看其中涉及的语法规则。
_asm 是GCC 关键字asm 的宏定义,是内嵌汇编的关键字,表示这是一条内嵌汇编语句。
_volatile 是GCC 关键字volatile的宏定义,告诉编译器不要优化代码,汇编指令保留原样
内嵌汇编关键字asm volatile 的括号内部第一部分是汇编代码,这里的汇编代码和之前学习的汇编代码有一点点差异,体现在%转义符号。寄存器前面多一个%的转义符号,有两个%, 而%加一个数字则表示第二部分输出、第三部分输入以及第四部分存坏描述的编号。
上述内嵌汇编范例中定义了3个变量val1, val2 和val3 , 希望求解val3 = val1 + val2, 下面具体分析.
第一行 “movl $0, %%eax" 是把EAX清0.
第二行 "addl %1, %%eax", %1 是指下面的输出和输入的部分,第一个输出编号为%0, 第二个为%1, 第三个为%2。 %1是指val1, 前面一个“c"是指用ECX寄存器存储val1的值,这样编译器在编译时就自动把val1的值放到ECX里面。%1实际上就是把ECX的值与EAX 寄存器求和然后放到EAX寄存器中,本例中由于EAX为0,所以结果就是ECX的值放放了EAX寄存器。
第三行 “addl %2, %%eax", %2 是指val2存在EDX寄存器,就是把val1的值加上val2的值再放到EAX里。
最后一条指令“movl %%eax, %0" 是把val2 加上val2的值存储的地方放到%0, %0就是val3, 我们这里用=m 修饰,它的意思就是写到内存变量里面去,m就是内存memory, 不是使用寄存器了,这条指令是直接把变量放到内存val3里面。
至此, 这段代码就实现了val3 = val1 + val2的功能。
简单总结一下,如果把内嵌汇编当作一个函数,则第二部分输出和第三部分输入相当于函数的参数和返回值,而第一部分的汇编代码则相当于函数内部的具体代码。
最后
以上就是紧张背包为你收集整理的一句话说清楚c代码中如何内嵌汇编的全部内容,希望文章能够帮你解决一句话说清楚c代码中如何内嵌汇编所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复