1.调用形式
标准形式:
asm("movl %ecx %eax");/* moves the contents of ecx to eax */
__asm__("movb %bh(%eax)"); /*moves the byte from bh to the memory pointed by eax*/
多行:
__asm__ ("movl %eax,%ebx\n\t"
"movl $56,%esi\n\t"
"movl %ecx,$label(%edx,%ebx,$4)\n\t"
"movb %ah,(%ebx)");
扩展形式:
asm ( assemblertemplate
: output operands /* optional */
: input operands /* optional */
: list ofclobbered registers /* optional */
);
2.实例
/*将a的值赋给b*/
inta=10, b;
asm("movl %1, %%eax;
movl%%eax, %0;"
:"=r"(b) /* output */
:"r"(a) /* input */
:"%eax" /* clobbered register */
);
3.说明:
Theformat islike: eithereach instructionshould beenclosed withindouble quotes,or theentire groupof instructionsshould bewithin doublequotes. Eachinstruction shouldalso endwith adelimiter. Operandscorresponding tothe Cexpressions arerepresented by%0, %1... etc.
Ifweusemorethanoneoperand,theyareseparatedbycomma.Intheassemblertemplate,eachoperandisreferencedbynumbers.Numberingisdoneasfollows.Ifthereareatotalofnoperands(bothinputandoutputinclusive),thenthefirstoutputoperandisnumbered0,continuinginincreasingorder,andthelastinputoperandisnumberedn-1.Themaximumnumberofoperandsisaswesawintheprevioussection.
寄存器与符号表示之间的关系如下表
限制符 | 说明 |
a | 对应的变量必须在EAX中 |
b | EBX |
c | ECX |
d | EDX |
S | ESI |
D | EDI |
q | EAX,EBX,ECX,EDX中的任何一个 |
r | EAX,EBX,ECX,EDX,ESI,EDI中的任何一个 |
A | EAX:EDX组合成一个64位的操作数 |
m | 操作数必须是内存中的变量 |
o | 操作数是内存变量,并且对操作数的寻址方式为基址加一个偏移量 |
V | 操作数是内存变量,但是寻址方式为基址,没有偏移量 |
g | 操作数可以是内存变量,立即数,EAX,EBX,ECX或者EDX |
I | 操作数是0~31的立即数(用于32位的移位操作) |
J | 操作数是0~63的立即数(用于64位的移位操作) |
K | 操作数必须是0xFF |
L | 操作数必须是0xFFFF |
M | 操作数是0,1,2,或3 |
N | 操作数可以是0-255中的任何一个数(用于in/out指令) |
f | 操作数是浮点寄存器 |
t | 第一个浮点寄存器 |
u | 第二个浮点寄存器 |
= | 操作数是只写的(用于输出) |
+ | 操作数是可读写的(用于输入输出) |
& | 表示在汇编代码前前,对应的操作数会输入部分修改 |
memory | 用在损坏部分中,表示内在被修改了 |
4.更多实例
//计算一个数的5倍
asm("leal (%1,%1,4), %0"
: "=r"(five_times_x)
: "r" (x)
);
//这个版本中输入和输出使用同一个寄存器
asm ("leal (%0,%0,4),%0"
: "=r"(five_times_x)
: "0" (x)
);
5. 处理跳转
条件分支和无条件分支都允许指定一个数字加上方向标志作为标签,方向标志指出处理器应该指向哪个方向查找数字型标签。第一个遇到的标签会被采用。
例子:
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
int result;
asm("cmp %1, %2\n\t"
"jge 0f\n\t"
"movl %1, %0\n\t"
"jmp 1f\n"
"0:\n\t"
"movl %2, %0\n"
"1:"
:"=r"(result)
:"r"(a), "r"(b));
printf("The larger value is %d\n", result);
return 0;
}
f后缀表示向前跳转,b后缀表示向后跳转。