【方辉专栏】ARM嵌入式编译器(十一) C文件内嵌汇编代码介绍
发布时间:2022-09-06

摘要: 本文主要对Arm Compiler 6编译器提供的内联汇编器。对C文件内嵌汇编代码的编写介绍。

关键字:Arm Compiler 6、编译器、 内联汇编器、C文件内嵌汇编


Arm Compiler 6集成了内联汇编器,可以为在C或C++代码中的GUN汇编进行编译。

例如:使用__asm关键字将GNU内联汇编代码合并到一个函数中。

#include <stdio.h>

int add(int i, int j)

{

  int res = 0;

  __asm ("ADD %[result], %[input_i], %[input_j]"

    : [result] "=r" (res)

    : [input_i] "r" (i), [input_j] "r" (j)

  );

  return res;

}

int main(void)

{

  int a = 1;

  int b = 2;

  int c = 0;

  c = add(a,b);

  printf("Result of %d + %d = %dn", a, b, c);

}


1. 内联汇编结构

__asm内联汇编语句结构:

/* 基本内联形式 */

__asm [volatile] (code);

/*扩展内联形式 */

__asm [volatile] (code_template:outputs[:inputs[:clobber_list]]);


code

汇编指令,例如"ADD R0, R1, R2".


code_template

汇编指令的模板,例如"ADD %[result], %[input_i], %[input_j]".


outputs

输出操作数列表,以逗号分隔。每个操作数由方括号中的符号名称、约束字符串和小括号中的C表达式。在此示例中,有一个输出操作数:[result] "=r" (res);

输出操作数列表也可以为空。

例如:

__asm ("ADD R0, %[input_i], %[input_j]"

:  /* 输出操作数为空 */

: [input_i] "r" (i), [input_j] "r" (j)

);


inputs

输入操作数的可选列表,以逗号分隔。输入操作数使用与输出操作数相同。在此示例中,有两个输入操作数:[input_i] "r" (i), [input_j] "r" (j).输入操作数列表也可以为空。


clobber_list

以逗号分隔的字符串列表。每个字符串都是汇编代码可能修改的寄存器的名称,但最终值并不重要。要防止编译器将寄存器用于内联汇编字符串中的模板字符串,请将寄存器添加到 clobber 列表中。


例如,如果一个寄存器包含一个临时值,则将其包含在 clobber 列表中。编译器避免使用此列表中的寄存器作为输入或输出操作数,或者在执行汇编代码时使用它来存储另一个值。

该列表可以为空。除了寄存器,列表还可以包含特殊参数:

"cc"

该指令修改条件代码标志。

"memory"

该指令访问未知的内存地址。

中的寄存器clobber_list必须使用小写字母而不是大写字母。带有 a 的示例指令clobber_list是:

__asm ("ADD R0, %[input_i], %[input_j]"

:  /*输出操作数为空 */

: [input_i] "r" (i), [input_j] "r" (j)

: "r5","r6","cc","memory"

);


2. 定义符号和标签

定义符号:

例如,__asm (".global __use_no_semihostingnt");


定义标签:在标签后需要加“:”。

例如,__asm ("my_label:nt");


3. 多条指令

在__asm一条语句中编写多条指令。

例如在下例中,使用一个__asm语句为 Arm®v8-M 架构编写的中断处理程序:

void HardFault_Handler(void)

{

__asm (

"TST LR, #0x40nt"

"BEQ from_nonsecurent"

"from_secure:nt"

"TST LR, #0x04nt"

"ITE EQnt"

"MRSEQ R0, MSPnt"

"MRSNE R0, PSPnt"

"B hard_fault_handler_cnt"

"from_nonsecure:nt"

"MRS R0, CONTROL_NSnt"

"TST R0, #2nt"

"ITE EQnt"

"MRSEQ R0, MSP_NSnt"

"MRSNE R0, PSP_NSnt"

"B hard_fault_handler_cnt"

);

}

将上面的处理程序代码复制到file.c,然后使用以下命令对其进行编译:

armclang --target=arm-arm-none-eabi -march=armv8-m.main -S file.c -o file.s


来源:《Arm® Compiler for Embedded User Guide Version 6.18》


+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


关于凯发k8一触即发电子

凯发k8一触即发电子技术有限公司(英文名称:Emdoor Electronics Technology Co.,Ltd)是国内资深的研发工具软件提供商,公司成立于 2002 年,面向中国广大的制造业客户提供研发、设计、管理过程中使用的各种软件开发工具,致力于帮助客户提高研发管理效率、缩短产品设计周期,提升产品可靠性。

20 年来,先后与 Altium、ARM、Ansys、QT、Adobe、Visu-IT、Minitab、Testplant、EPLAN、HighTec、GreenHills、PLS、Ashling、MSC Software 、Autodesk、Source Insight、TeamEDA、MicroFocus等多家全球知名公司建立战略合作伙伴关系,并作为他们在中国区的主要分销合作伙伴服务了数千家中国本土客户,为客户提供从芯片级开发工具、EDA 设计工具、软件编译以及测试工具、结构设计工具、仿真工具、电气设计工具、以及嵌入式 GUI 工具等等。凯发k8一触即发电子凭借多年的经验积累,真正的帮助客户实现了让研发更简单、更可靠、更高效的目标。

欢迎关注“凯发k8一触即发电子”公众号

了解更多研发工具软件知识