实现val3 = val1 + val2
函数
#include <stdio.h>
void myAdd(int val1, int val2){
int val3 = 0;
printf("val1=%d, val2=%d, val3=%d\n", val1, val2, val3);
asm volatile(
"movl $0, %%eax\n\t"
"addl %1, %%eax\n\t"
"addl %2, %%eax\n\t"
"movl %%eax, %0\n\t"
:"=m"(val3)
:"c"(val1), "d"(val2)
);
printf("val1=%d, val2=%d, val3=%d\n", val1, val2, val3);
}
int main(){
myAdd(1, 2);
return 0;
}
__asm__
和asm
等价,__volatile__
和volatile
等价。
寄存器前要加一个%
转移符号。
%0,%1..
是指输入输出部分,第一个编号为%0
。
"a"
、"c"
和"d"
是将变量放到eax
,ecx
和edx
寄存器中。
volatile
用于关闭编译器优化
asm内嵌汇编代码语法
asm volatile (
"asm code\n\t"
:output
:input
:changed
);
output表示的是从ASM到C语言输出,简单理解就是寄存器到变量的操作;而input相反,指的是C变量到ASM寄存器赋值的过程。
input和output格式为[asm代码中用到的符号]"内容限定"(C代码中的变量)
-
[]
符号可以省略,改成%0,%1
等代替。 -
内容限定
简单约束符
r 使用任何可用的寄存器
m 使用变量的内存地址
i 使用立即数
约束修饰符:在上面的简单约束符开头可以增加下面的约束修饰符来决定它们的可读写特性。
'=': 表示操作数会被指令直接赋值,之前的值会被清除,这意味这该操作数之前的值并不重要;
'+': 表示操作数既会被指令读,也会被指令写;对于既没有指定'=',也没有指定'+'的操作数,会被认为是只读的;
因此上面代码的一个等效代码如下
#include <stdio.h>
void myAdd(int val1, int val2){
int val3 = 0;
printf("val1=%d, val2=%d, val3=%d\n", val1, val2, val3);
asm volatile(
"movl $0, %%eax\n\t"
"addl %[input1], %%eax\n\t"
"addl %[input2], %%eax\n\t"
"movl %%eax, %[output]\n\t"
:[output]"=m"(val3)
:[input1]"c"(val1), [input2]"d"(val2)
);
printf("val1=%d, val2=%d, val3=%d\n", val1, val2, val3);
}
int main(){
myAdd(1, 2);
return 0;
}
标签:内嵌,汇编,%%,C语言,eax,val3,val2,val1,asm
From: https://blog.51cto.com/u_15457669/5786015