专题 18 Inline Assembly(在C语言中嵌套使用汇编)

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

EAXEBXECXEDXESIEDI中的任何一个

A

EAXEDX组合成一个64位的操作数

m

操作数必须是内存中的变量

o

操作数是内存变量,并且对操作数的寻址方式为基址加一个偏移量

V

操作数是内存变量,但是寻址方式为基址,没有偏移量

g

操作数可以是内存变量,立即数,EAXEBXECX或者EDX

I

操作数是0~31的立即数(用于32位的移位操作)

J

操作数是0~63的立即数(用于64位的移位操作)

K

操作数必须是0xFF

L

操作数必须是0xFFFF

M

操作数是012,或3

N

操作数可以是0255中的任何一个数(用于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后缀表示向后跳转。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值