当前位置: 首页 > news >正文

ARM GCC内联汇编

ARM GCC内联汇编

    • 通用的内嵌汇编模板
      • Example
    • Operand List中修饰符
      • Example
    • Clobber List
      • Example

通用的内嵌汇编模板

__asm volatile (code:output operand list:input operand list:clobber list
);

Example

C内联汇编:
// __attribute__((naked))
__attribute__((noinline))
uint8_t asm_test(uint8_t a, uint8_t b)
{uint8_t c;__asm volatile ("adds %[res], %[src0], %[src1]\n\t":[res] "=r" (c):[src0] "r" (a), [src1] "r" (b):);return c;
}反汇编代码:
0040a350 <asm_test>:40a350:	1840      	adds	r0, r0, r140a352:	b2c0      	uxtb	r0, r040a354:	4770      	bx	lr
  • 使用__attribute__((naked)可以使函数开头和结尾没有保存和恢复的指令(由编译器自动添加),使用__attribute__((noinline))可以使函数不被优化为嵌入某个函数的汇编指令,而是保持一个函数的形式。
  • 使用operand list与C函数的变量和入参进行交互,格式为[alias] "修饰符" (C variable),使用[]和()绑定变量的语法很像超链接,比如[Good](https://google.com)。
  • operand list中的各项以逗号,分隔
  • 对于早期gcc,不支持使用alias标识变量,而是使用%0,%1…这种根据变量出现的顺序编号,这样的缺陷在于一旦中间加一个操作符,所有的编号都变了
  • 使用volatile可以禁止编译器优化,用于将咱写的汇编指令都编译出来,比如mov r0, r0就不会再被优化

Operand List中修饰符

  • 定义数据类型

在这里插入图片描述

  • 输入输出类型
Modifier含义
=write-only,仅用于output operand list
+read-write,定义操作数可读可写,仅用于output operand list
&指示编译器将变量绑定到特定的寄存器,避免与其它寄存器冲突,引发输出值被改变的问题,&只能放在+/=之后

没有=,+修饰的操作符都是read-only的,input operand list都是read-only,所以想对同一变量又读又写,那只能将它放在output operand list并用+修饰。

Example

  1. 立即数搭配宏进行使用,因为内联汇编里的东西没法被预处理
#define A 20void demo(void)
{__asm volatile ("mov r0, %[imm]\n\t"::[imm] "I" (A):);
}/* -------------------对应汇编----------------------- */
0040a364 <demo>:40a364:	f04f 000a 	mov.w	r0, #1040a368:	4770      	bx	lr
  1. &的作用
/* ---------------------正确写法带&----------------------- */
uint32_t tab[2];
uint8_t asm_test(uint8_t a, uint8_t b)
{uint32_t rdv, wdv=1;__asm volatile ("ldr %[rd], [%[tab]]\n\t""str %[wr], [%[tab], #4]\n\t":[rd] "=&r" (rdv):[tab] "r" (tab),[wr] "r" (wdv):);return 1;
}
/* ---------------------对应汇编----------------------- */
0040a350 <asm_test>:40a350:	2001      	movs	r0, #140a352:	4b02      	ldr	r3, [pc, #8]	@ (40a35c <asm_test+0xc>)40a354:	681a      	ldr	r2, [r3, #0]40a356:	6058      	str	r0, [r3, #4]40a358:	4770      	bx	lr40a35a:	bf00      	nop40a35c:	200023fc 	.word	0x200023fc/* ---------------------错误写法无&----------------------- */
uint32_t tab[2];
uint8_t asm_test(uint8_t a, uint8_t b)
{uint32_t rdv, wdv=1;__asm volatile ("ldr %[rd], [%[tab]]\n\t""str %[wr], [%[tab], #4]\n\t":[rd] "=r" (rdv):[tab] "r" (tab),[wr] "r" (wdv):);return 1;
}
/* ---------------------对应汇编----------------------- */
0040a350 <asm_test>:40a350:	2001      	movs	r0, #140a352:	4b02      	ldr	r3, [pc, #8]	@ (40a35c <asm_test+0xc>)40a354:	681b      	ldr	r3, [r3, #0]40a356:	6058      	str	r0, [r3, #4]40a358:	4770      	bx	lr40a35a:	bf00      	nop40a35c:	200023fc 	.word	0x200023fc

在错误的写法中,由于不带&,造成rd和tab共用了寄存器r3;加上&后,rd用的r2,没有受到干扰,这些行为和编译器类型及版本有关系,为了避免出错,直接将output operand list都加上&修饰

Clobber List

破坏列表,告诉编译器我在这段汇编代码中改变了什么,比如改变了寄存器,内存等等,这样编译器会在执行这段汇编代码之前保存一下将被改变的数据。

类型含义
r0, r1…表示寄存器将被改变,在执行汇编之前将push对应的寄存器,并在执行完汇编之后pop出来
memory告诉编译器内存将会被改变,在执行汇编之前,将那些还未写入内存的值赶紧写入
cc告诉编译器condition code状态寄存器将改变

Example

对于memory和cc没构建出好的例子,只有关于寄存器的了。

/*--------------------------C--------------------------*/
uint8_t asm_test(uint8_t a, uint8_t b)
{__asm volatile ("mov r0, r0\n\t":::"r4");return 0;
}/*--------------------------汇编--------------------------*/
0040a350 <asm_test>:40a350:	b510      	push	{r4, lr}40a352:	4600      	mov	r0, r040a354:	2000      	movs	r0, #040a356:	bd10      	pop	{r4, pc}

果然编译器对咱指定的"r4"做了保存恢复的操作。


文章转载自:
http://adrenocorticotro.isnyv.cn
http://assertive.isnyv.cn
http://apathy.isnyv.cn
http://bullhead.isnyv.cn
http://backsaw.isnyv.cn
http://beset.isnyv.cn
http://abortarium.isnyv.cn
http://bouillabaisse.isnyv.cn
http://amateurism.isnyv.cn
http://becalmed.isnyv.cn
http://chromizing.isnyv.cn
http://arena.isnyv.cn
http://barothermohygrogram.isnyv.cn
http://alanyl.isnyv.cn
http://architecture.isnyv.cn
http://alpeen.isnyv.cn
http://chairside.isnyv.cn
http://apprehensively.isnyv.cn
http://autolysis.isnyv.cn
http://asteria.isnyv.cn
http://attending.isnyv.cn
http://cheilitis.isnyv.cn
http://asyntactic.isnyv.cn
http://bonzer.isnyv.cn
http://acouophonia.isnyv.cn
http://calix.isnyv.cn
http://automatically.isnyv.cn
http://cabalism.isnyv.cn
http://beggardom.isnyv.cn
http://cadastral.isnyv.cn
http://www.dtcms.com/a/280745.html

相关文章:

  • 如何轻松将音乐从安卓设备传输到安卓设备
  • 用vue自定义指令设置页面权限
  • Android 事件机制详解
  • day053-初识docker与基础命令
  • 广东省省考备考(第四十六天7.15)——判断推理:位置规律(听课后强化训练)
  • SD-WAN 技术在新能源行业的应用与优选方案分析
  • 【华为机试】3. 无重复字符的最长子串
  • 光米投影 多余之物的本思
  • 怎么样才能入门深度学习?
  • element plus使用插槽方式自定义el-form-item的label
  • NW917NW921美光固态闪存NW946NW952
  • 1.2 vue2(组合式API)的语法结构以及外部暴露
  • Vue框架之模板语法(插值表达式、指令系统、事件处理和表单绑定)全面解析
  • MATLAB 安装 ACADO 的完整步骤
  • 简单工厂设计模式
  • Web应用防火墙(WAF)技术
  • vue实现el-table-column中自定义label
  • 全局 WAF 规则:构筑 Web 安全的坚固防线
  • Git基础概念与常用命令详解
  • x86版的ubuntu上使用qemu运行arm版ubuntu
  • Java项目:基于SSM框架实现的网盘管理系统【ssm+B/S架构+源码+数据库+毕业论文】
  • EMS4100芯祥科技USB3.1高速模拟开关芯片规格介绍
  • iOS高级开发工程师面试——多线程
  • LVS三种模式实战
  • Unity沉浸式/360View/全景渲染
  • 新手向:Python数据处理Excel报表自动化生成与分析
  • Zookeeper入门安装与使用详解
  • Java行为型模式---迭代器模式
  • Linux、Ubuntu和CentOS的关系与区别
  • 设计模式笔记_结构型_适配器模式