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.说明:
AssemblerTemplate:
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后缀表示向后跳转。