C语言嵌入汇编Extended ASM

Extended ASM

在程序中可能需要对寄存器进行操作,而使用C/C++无法直接对寄存器进行操作,这就要用到嵌入汇编

基本语法

嵌入汇编的基本语法如下:

asm asm-qualifiers (
    "AssemblerTemplate"  // 汇编指令,使用\n分割,可写多行
    : OutputOperands     // 输出
    : InputOperands      // 输入
    : Clobbers           // 汇编代码更改的寄存器,使用','分割,具体用法看demo
    : GotoLabels)
  • AssemblerTemplate
    This is a literal string that is the template for the assembler code. It is a combination of fixed text and tokens that refer to the input, output, and goto parameters.

  • OutputOperands
    A comma-separated list of the C variables modified by the instructions in the AssemblerTemplate. An empty list is permitted.

  • InputOperands
    A comma-separated list of C expressions read by the instructions in the AssemblerTemplate. An empty list is permitted.

  • Clobbers
    A comma-separated list of registers or other values changed by the AssemblerTemplate, beyond those listed as outputs. An empty list is permitted

  • GotoLabels
    When you are using the goto form of asm, this section contains the list of all C labels to which the code in the AssemblerTemplate may jump.

常用的限制符,在此借用知乎上的一张图片

在这里插入图片描述

demo

下面以C语言 x86汇编为例,涉及到两个函数setadd

可使用gcc编译运行。

// demo.c
#include <stdio.h>

int set(int src) {
  int dst = 0;
  asm volatile (
    "mov %1, %0\n\t"
    :"=r"(dst)
    :"r"(src)
  );

  return dst;
}

int add(int src1, int src2) {
  int dst = 0;
  asm volatile (
    "movl %1, %%edi\n\t"
    "movl %2, %%esi\n\t"
    "addl %%esi, %%edi\n\t"
    "movl %%edi, %0\n\t"
    :"=r"(dst)
    :"r"(src1), "r"(src2)
    :"edi", "esi"
  );

  return dst;
}

int main() {
  int value = 11;
  int ret = set(value);
  printf("value = %d\n", value);
  printf("ret = %d\n", ret);

  printf("==========\n");
  int src1 = 22;
  int src2 = 33;
  int result = add(src1, src2);
  printf("result=%d\n", result);
}

set

asm volatile (
  "mov %1, %0\n\t"
  :"=r"(dst)
  :"r"(src)
);

汇编指令mov rbx,rax就是将寄存器rax的值赋给rbx

按照extended asm的基本语法,对上面的汇编进行简单的介绍.

dst为输出,src输入

add

asm volatile (
    "movl %1, %%edi\n\t"
    "movl %2, %%esi\n\t"
    "addl %%esi, %%edi\n\t"
    "movl %%edi, %0\n\t"
    :"=r"(dst)
    :"r"(src1), "r"(src2)
    :"edi", "esi"
  );

这里主要展示,如果有多个输入和对多个寄存器进行修改(使用),该如何使用。

[1] https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#OutputOperands

[2] https://zhuanlan.zhihu.com/p/348372132

[3] https://zhuanlan.zhihu.com/p/443522525?msclkid=4113a2f5d07211eca98977dff79fb325

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值