内联汇编

1.gcc编译程序支持的另一种编码形式是内联汇编(inline assembly)代码。内联汇编不需要调用单独编译的汇编程序。我们可以通过特定的结构告诉编译程序将代码组合到一起,而不是要编译该代码块。虽然这样做会生成体系结构相关的文件,但能大大提高C函数的可读性并提高其执行效率。

内联汇编程序的结构:

asm ( assembler instruction (s)

 :output operands (optional)

 :input operands(optioanl)

 : clobbered registers (optional)

);

 

内联汇编程序最基本的形式是:

asm ("movl %eax,%ebx");

也可以写成:

asm ("movl %eax,%ebx" : : :);

输出操作数:是一个C表达式列表,其后的圆括号中是约束条件。约束条件通常用“=”来表示,表示“只写”;“&”表示这是一个已经被修改过的操作数

输入操作数:语法同上,只是不用“=”修饰

修改过的寄存器:列出修改过的寄存器和内存

2.参数的编号方式

所有参数从0开始统一编号

例如,若有一个输出参数和2个输入参数,则%0是输出参数,%1和%2都是输入参数

3.约束条件

a:寄存器eax

b:寄存器ebx

c:寄存器ecx

d: 寄存器edx

S:寄存器esi

D:寄存器edi

I:常数(0....31)

q:从eax,ebx,ecx,edx动态分配一个寄存器

r:与q+esi,edi一样

m:内存定位

A:与a+b的作用一样。同时分配eax和ebx,形成一个64位寄存器

。。。。。

_volatile_:不要优化

例1:

int foo(void)

{

    int ee=0x4000,ce=0x8000,reg;

    _asm_  _volatile_("movl %1,%%eax",//将ce的值传给eax

    "movl %2,%%ebx";//将ee的值传给ebx

    "call setbits";//在汇编程序中调用函数

    "movl %%eax,%0"//将返回值存储到eax中,并将其复制给reg

    : "=r"(reg)//输出参数列表,reg属性为只写

    : "r"(ce),"r"(ee)//输入参数列表,ce和ee是寄存器变量

    : "%eax","%ebx"//寄存器修改列表,

)

printf("reg=%x",reg);

 

}

例2:

#define switch_to(prev,next,last) do{

 unsigned long esi,edi;//局部变量

 asm volatile(

"pushfl /n/t"

"pushl %%ebp/n/t"

 "movl %%esp,%0/n/t"//把esp值复制给prev->thread.esp

" movl %5,%%esp/n/t"//将next->thread.esp赋值给esp

" movl $1f,%1/n/t"//保存eip的值

"pushl  %6/n/t"//重新给eip赋值

"jmp _switch_to /n"

"1:/t"//参数被用作返回地址

"popl %%ebp/n/t"

"popfl"

:"=m" (prev->thread.esp),"=m"(prev->thread.eip),"=a"(last),"=S"(esi),"=D"(edi)//输出参数列表

:"m"(next->thread.esp),"m"(next->thread.eip),"2"(prev),"d"(next)//输入参数列表

);

}while(0)

/n/t与汇编程序的接口有关。每条汇编指令都应该在各自的线路上运行

输出参数列表:

[%0]=(prev->thread.esp),只写内存

[%1]=(prev->thread.eip),只写内存

[%2]=(last),对寄存器eax只写

[%3]=(esi),对寄存器esi只写

[%4]=(edi),对寄存器edi只写

输入参数列表:

[%5]=(next->thread.esp),内存

[%6]=(next->thread.eip),内存

[%7]=(prev),重新使用2号参数(寄存器eax)作为输入

[%8]=(next),是赋给寄存器edx的一个输入

此处没有已修改寄存器列表

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值