内联汇编__asm和__asm__的区别是什么
时间: 2024-01-12 13:22:43 浏览: 337
__asm 和 __asm__ 都是用于在C或C++代码中嵌入内联汇编的关键字。它们的区别在于它们在不同的编译器中的使用方式和行为。
在某些编译器中,如GCC,使用 __asm 关键字来嵌入内联汇编代码。例如:
```c
__asm__("movl %eax, %ebx");
```
而在其他编译器中,如Visual C++,使用 __asm__ 关键字来嵌入内联汇编代码。例如:
```c
__asm {
mov eax, ebx
}
```
需要注意的是,__asm 和 __asm__ 的使用方式和语法可能会因编译器而异。因此,在编写嵌入式汇编代码时,应该参考特定编译器的文档和规范。
相关问题
gcc内联汇编asm格式详解
GCC内联汇编asm格式是一种将汇编代码嵌入到C或C++源代码中的方法。它允许开发人员直接使用汇编语言来访问底层硬件或执行高性能算法。以下是GCC内联汇编asm格式的详细说明。
基本格式
GCC内联汇编asm格式基本格式如下:
```c
asm (assembly code : output operands : input operands : clobbered registers);
```
- assembly code:汇编代码,可以是单行或多行代码。
- output operands:用于存储计算结果的变量,可以有多个,用逗号分隔。输出操作数是可选的,可以省略。
- input operands:用于传递参数的变量,可以有多个,用逗号分隔。输入操作数是必需的。
- clobbered registers:代码执行期间会被修改的寄存器,用于通知编译器。可以有多个,用逗号分隔。clobbered registers是可选的,可以省略。
示例
以下是一个简单的GCC内联汇编asm格式示例,将eax寄存器中的值加1,并将结果存储在eax中。
```c
int value = 10;
asm ("addl $1, %%eax" : "=a" (value) : "a" (value));
```
- "addl $1, %%eax":汇编代码,将eax加1。
- "=a" (value):输出操作数,将eax中的值存储在value变量中。
- "a" (value):输入操作数,将value的值传递给eax。
- 没有clobbered registers。
输出操作数
输出操作数用于将汇编代码的结果存储在变量中。输出操作数有两种类型:普通输出(通道约束)和跨约束输出。
普通输出
普通输出使用“=约束”语法表示,其中约束指定了输出操作数应存储在哪个寄存器或内存位置中。约束可以是以下之一:
- "=r"(任意寄存器)
- "=m"(任意内存位置)
- "=a"(eax寄存器)
- "=d"(edx寄存器)
- "=q"(eax或edx寄存器)
示例
以下是一个使用普通输出的示例,将eax寄存器中的值加1,并将结果存储在value变量中。
```c
int value;
asm ("addl $1, %%eax" : "=a" (value) : "a" (value));
```
跨约束输出
跨约束输出是一种将结果存储在多个输出变量中的方法。它使用“+约束”语法表示,其中约束指定了输出操作数应存储在哪个寄存器或内存位置中。多个约束可以用逗号分隔。
示例
以下是一个使用跨约束输出的示例,将eax寄存器中的值加1,并将结果存储在value1和value2变量中。
```c
int value1, value2;
asm ("addl $1, %%eax" : "+a" (value1), "=r" (value2));
```
输入操作数
输入操作数用于将变量的值传递给汇编代码。输入操作数使用“约束”语法表示,其中约束指定了变量应该存储在哪个寄存器或内存位置中。约束可以是以下之一:
- "r"(任意寄存器)
- "m"(任意内存位置)
- "a"(eax寄存器)
- "d"(edx寄存器)
- "q"(eax或edx寄存器)
示例
以下是一个使用输入操作数的示例,将value变量的值传递给eax寄存器中。
```c
int value = 10;
asm ("movl %0, %%eax" : : "r" (value));
```
clobbered registers
clobbered registers是在汇编代码执行期间会被修改的寄存器列表。它用于通知编译器哪些寄存器应该被保存和恢复。clobbered registers使用“%约束”语法表示,其中约束指定了被修改的寄存器名称。多个寄存器可以用逗号分隔。
示例
以下是一个使用clobbered registers的示例,将eax寄存器中的值加1,并告诉编译器edx寄存器也被修改了。
```c
asm ("addl $1, %%eax" : : "a" (value) : "%edx");
```
总结
GCC内联汇编asm格式是一种将汇编代码嵌入到C或C++源代码中的方法。它允许开发人员直接使用汇编语言来访问底层硬件或执行高性能算法。通过输出操作数、输入操作数和clobbered registers,开发人员可以管理汇编代码与C或C++代码之间的数据流和寄存器使用。
void enable_IRQ(void) { int tmp; _ _asm //声名内联汇编代码 { MRS tmp, CPSR BIC tmp, tmp, #0x80 MSR CPSR_c, tmp }
这段代码中,使用了 ARM 处理器的内联汇编指令来实现开启中断的功能。具体来说,它使用 MRS 指令将当前程序状态寄存器 CPSR 的值读入 tmp 变量中,然后使用 BIC 指令对 tmp 进行位操作,将 CPSR 的第 7 位(即 IRQ 禁止位)清零,最后使用 MSR 指令将修改后的值写回 CPSR 中。这样就实现了开启中断的功能。
阅读全文