GCC内联汇编(INLINE ASSEMBLY) 转

本文深入探讨GCC内联汇编的功能与应用,解释了如何在C代码中嵌入汇编指令,以实现对CPU特权指令的直接调用和代码优化。通过具体实例,展示了内联汇编的语法及关键字,如volatile、%0、r等,并对比了内联汇编与普通汇编的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GCC内联汇编(INLINE ASSEMBLY)
  什么是内联汇编(Inline assembly)?

1、这是GCC对C语言的扩张,就是在C代码里面去写汇编代码

2、可以直接在C的语句中插入汇编指令

有何用处?

1、C语言不足以完成所有CPU的指令, 特别是有一些特权指令,比如加载gdt表(Global Descriptor Table 全局描述符表),从而使用汇编代码来完成

2、用汇编在C语言中手动优化,特别是在操作系统当中,使用汇编对操作系统的掌控更为精准,更加准确。

如何工作?

1、用给定的模板和约束来生成汇编指令

2、才C函数内形成汇编代码

下面一个小例子,简单看一下汇编代码和内联汇编的不同:

GCC内联汇编-Example 1

汇编代码 Assembly(*.S):

movl $0xffff, %eax //把0xffff给eax

内联汇编 Inline assembly(*.c):

asm(“movl $0xffff, %%eax\n”) //1、加了一个内联汇编关键字asm,把汇编代码括起来然后用引号表示一个字符串 2、寄存器前变为%%

GCC内联汇编-语法
  asm(“assmbler template” //assmbler template就是example 1 的那个字符串的内容(汇编语句)

:output operands (optional)  //可选的输出操作数(输出寄存器)

:input operands (optional)  //可选的输入操作数(输入寄存器)

:clobbers (optional)  //会被修改的寄存器

);

GCC内联汇编-Example2
Inline assembly(*.c)

uint32_t cr0;                  //一个叫cr0的变量

asm volatile(“movl %%cr0, %0\n” :"=r"(cr0));   //把cr0里面的内容读到%0这个寄存器当中, =r这个寄存器的内容会赋给cr0这个变量(输出操作)

cr0 |= 0x80000000;              //把某一个位设成1

asm volatile(“movl %0, %%cr0\n” ::“r”(cr0));   //再把cr0变量里的内容写回到cr0寄存器当中。把cr0给一个寄存器,然后这个寄存器再把他里面的内容赋给cr0寄存器(输入操作)

一些关键字的含义

volatile:No reordering; No elimination. 不需要进一步的优化,不需要进一步的调整顺序

%0  :The first constraint following. 第一个用到的寄存器

r    :A constraint; GCC is free to use any register. 任意一个寄存器

上面的内联汇编所对应的汇编代码如下

Generated assembly code(*.s):

movl %cr0, %ebx //cr0 --> ebx

movl %ebx, 12(%esp) //ebx赋给一个局部变量12(%esp)

orl $-2147483648, 12(%esp) //或操作

movl 12(%esp), %eax //再给eax

movl %eax, %cr0        //再把eax寄存器里面的内容赋给cr0

GCC内联汇编-Example3
Inline assembly(*.c)

long _res, arg1 = 2, arg2 = 22, arg3 = 222, arg4 = 233;

_asm_volatile(“int $0x80”

:"=a"(_res)

:“0”(11), “b”(arg1), “c”(arg2), “d”(arg3), “S”(arg4)); //把arg1给ebx, arg2给ecx,arg3给edx, arg4给esi

在内联汇编当中

a = %eax, b = %ebx, c = %ecx, d = %edx, S = %esi, D = %edi, 0 = same as the first 第一个出现的寄存器

Generated assembly code(*.s):

mov $11, %eax

movl-28(%ebp), %ebx

movl-24(%ebp), %ecx

movl-20(%ebp), %edx

movl-16(%ebp), %esi

int $0x80

movl %edi, -12(%ebp)

如果想要了解GCC内联汇编更多的知识,请访问

Inline assembly for x86 in Linux
http://www.ibm.com/developerworks/library/l-ia/index.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值