keil把c语言函数转成汇编

汇编可以让开发人员从根源上理解程序的运行逻辑,本文介绍如何在keil环境下如何把一个c文件中的某一个函数,转换为汇编函数,并编译运行。

右击某个c文件,选择Option for File。。。

  图1

然后把下图中的Generate Assembler SRC File(生成汇编源文件)打黑色勾。(默认是灰色勾)

图2

然后执行编译,这样就会在工程的输出文件夹(一般会被命名为OBJ)下,找到与.c文件同名的.s文件,这个C文件中的所有函数,都会被一一转换为汇编函数。

以我的ad.c为例,里面有个test()函数,这个函数中会调用另外一个函数uint16_t AD_getValue1(void),还会对一个全局变量var做写操作。

图3

转换出的汇编函数如下:

图4

由这段代码可以看到在汇编中是如何调用C函数的,以及汇编是如何读写c语言中的全局变量var的。

写var的代码是这两行:

图5

首先LDR指令从|L0.260|标签处载入var变量的内存地址,然后VSTR指令把s0的值写入该内存地址处。汇编中的标签和C语言中的goto语句标签,是类似的。

那么|L0.260|标签定义了什么?在s文件中搜索可见:

图6

有上图可见,这个标签对应的flash地址处,通过DCD命令占用了一个32bit的空间,这个空间中的值被初始化成了全局变量var的地址。DCD本身并不是一个可执行语句,只是一个占位而已。

上图还可以看到,对于C语言中定义的很多常量,也用DCD命令给保存下来了。

接下来我们就可以把c语言中的这个test()函数,用汇编给替换一下:

float var;
void test(void)
{
	volatile float k = 1.5f;
	
	var = AD_getValue1() * k;
}

//前缀__asm代表这是个汇编语言编写的函数,以便编译时供编译器识别
__asm void test(void)
{
	THUMB
    REQUIRE8
    PRESERVE8
    //本汇编函数所有要调用的c函数,必须全部用IMPORT指令导入,不然编译报错
    IMPORT AD_getValue1[CODE]
    
    //全局变量也必须IMPORT导入
    IMPORT var
    
//以下代码直接从生成的.s文件中对应的test函数拷贝而来,见前文图4,我加了注释
        PUSH     {r3,lr}//PC指针存储到如r3寄存器
        VMOV.F32 s0,#1.50000000//把常量1.5加载到浮点寄存器s0中
        VSTR     s0,[sp,#0]//把s0中的值,存储到(sp指针+0)指向的内存处
        BL       AD_getValue1//调用c函数,其返回值(uint16类型)会被存到r0寄存器
        VMOV     s0,r0//把R0寄存器中的数转存到浮点寄存器s0中
        VCVT.F32.U32 s0,s0//把s0中的值由uint类型转成float类型
        VLDR     s1,[sp,#0]//把(sp指针+0)内存处的值加载到s1中
        VMUL.F32 s0,s0,s1//等价于s0=s0*si
        LDR      r0,|L0.260|/从|L0.260|标签处载入全局变量var的地址
        VSTR     s0,[r0,#0]//把s0中的值存储到var中
        POP      {r3,pc}//函数返回
//以上代码需要调用|L0.260|标签处的数据,也手动复制进来:
    |L0.260|
        DCD      var
}

至此,这个汇编函数__asm void test(void)和C语言函数void test(void),功能完全一致了。把这个c函数void test(void)删掉后,只保留汇编函数,仍然可以编译通过。这样我们就实现了:在一个c源文件中,既有c函数,又有汇编函数共存。

如果编译时看到以下报错:

error: A1875E: Register Rn must be from R0 to R7 in this instruction

 报错对应的代码为LDR      r0,|L0.260|,这行代码本身并没有问题,问题出在|L0.260|这个标签没有4字节对齐。

同时伴随上述报错的,还有一个警告:

 warning: A1581W: Added 2 bytes of padding at address 0x2aa

这个你警报的意思是ROM没有4字节对齐,编译器自动添加了2字节的空白。这个问题来源于图6中第一行DCW,这个指令占用了2字节的位置,导致后面的DCD无法4字节对齐了。解决方法就是直接把DCW这行删掉。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/566075.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux I2C(二) - I2C软硬件架构

1,I2C的总线拓扑 2,I2C S/W topology linux kernel I2C framework使用如下的软件拓扑抽象I2C硬件(我们可以一起领会一下其中的“设备模型”思想): 1)platform bus(/sys/bus/platform&#xff0…

【论文笔记 | 异步联邦】 FedBuff

1. 论文信息 Federated Learning with Buffered Asynchronous Aggregation,International Conference on Artificial Intelligence and Statistics,2022,ccfc 2. introduction 2.1.1. 背景: 同步 FL ,随训练过程中…

3D MINS 多模态影像导航系统

3D MINS多模态影像导航系统(Multimodal Image Navigation System)是SunyaTech研发的建立在DICOM(Digital Imaging and Communications in Medicine)图像基础之上的多模态影像导航系统,集二维影像PACS管理、三维影像层级…

在誉天学习云计算HCIE,担心考试考不过?

誉天定制化课程内容覆盖了所有考试重点,可以系统地掌握理论与实践知识。 对于笔试,类似于备考驾照理论学习阶段,誉天为大家提供在线模拟测试系统,帮助大家掌握云计算笔试考点。笔试通过后,18个月内(一年半…

html显示PDF并兼容IE浏览器的解决方案

方案一、vue-pdf插件 缺点&#xff1a;IE11显示空白&#xff0c;编译后的Edge测试环境可以正常线上&#xff0c;打到线上报错&#xff0c;谷歌和百分浏览器显示完美 1、vue 只显示核心代码&#xff0c;需要安装vue-pdf插件 <vue-pdf :src"ivcPdfUrl"></v…

【51单片机项目】基于51单片机自制多功能小键盘/模拟USB键盘【附源码】(STC89C52RC+CH9328)

目录 一、效果展示 二、创作灵感 三、硬件电路 注意事项 工作原理 四、源码 main.c 五、附录 CH9328工作原理 CH9328的模式选择 ​编辑 全键盘键码值表 参考链接 一、效果展示 该小键盘具有三种功能&#xff1a; 1、自动输入开机密码 2、每隔一段时间自动按下ct…

展商企业【广东伟创科技开发有限公司】| 2024水科技大会暨技术装备成果展

企业介绍 广东伟创科技开发有限公司成立于2006年&#xff0c;位于广东省江门市。公司是华南理工大学造纸与污染控制国家工程研究中心科技成果转化单位&#xff1b;是华南理工大学产学研合作单位&#xff1b;是广东省高新技术企业&#xff1b;是江门市现代信息服务业重点企业&am…

HarmonyOS ArkUI实战开发-手势密码(PatternLock)

ArkUI开发框架提供了图案密码锁 PatternLock 组件&#xff0c;它以宫格图案的方式输入密码&#xff0c;用于密码验证&#xff0c;本节读者简单介绍一下该控件的使用。 PatternLock定义介绍 interface PatternLockInterface {(controller?: PatternLockController): PatternL…

CSS中的层叠上下文

HTML 文档中的三维概念 平时我们从设备终端看到的 HTML 文档都是一个平面的&#xff0c;事实上 HTML 文档中的元素却是存在于三个维度中。除了大家熟悉的平面画布中的 x 轴和 y 轴&#xff0c;还有控制第三维度的 z 轴。 其中 x 轴通常用来表示水平位置&#xff0c;y 轴来表示…

爱普生RX-8130CE内置电池控制 RTC

特点&#xff1a;(1)封装极小&#xff0c;集成度高RX-8130CE是一个带|2C接口的实时时钟模块&#xff0c;内部集成32.768KHz晶体振荡器。实时时钟功能不仅集成了年、月、日、星期、小时、分、秒的日历和时钟计数器&#xff0c;同时也有时间闹钟、间隔定时器、时间更新中断等功能…

Qt [获取Dump] 使用WindowsAPI实现生成MiniDump文件

说明 客户现场的软件偶发崩溃是程序开发者&#xff0c;比较头疼的事情。如何更快速的定位到问题点和解决掉&#xff0c;是开发应该具备的基本能力。 Windows提供了一系列的API&#xff0c;可以记录软件崩溃前的堆栈信息。下面就实现一个生成Dump文件的程序实例。 主要代码 回…

unity读写本地excel_2024.4.22

using System.Collections; using System.Collections.Generic; using UnityEngine; using OfficeOpenXml; using System.IO; using Excel; using System.Data; using System; /// <summary> /// https://blog.csdn.net/Xz616/article/details/128893023 /// Unity3D操作…

JVM垃圾收集器--分代收集器

垃圾收集器主要分为两大类&#xff1a;分区收集器和分代收集器。分代收集器的代表是CMS&#xff0c;分区收集器的代表是G1和和ZGC。 分代收集器 CMS CMS收集器是第一个关注GC停顿时间&#xff08;stw时间)的收集器&#xff0c;采用“标记-清除”算法&#xff0c;之前的垃圾收…

《动手学深度学习(Pytorch版)》Task01:初识深度学习——4.22打卡

深度学习介绍 AI地图 自然语言处理&#xff1a;起源于符号学&#xff0c;如机器翻译&#xff0c;人在几秒钟能反应过来&#xff0c;属于感知问题计算机视觉&#xff1a;图片由像素组成&#xff0c;难以用符号学解释&#xff0c;在图片中进行推理&#xff0c;大部分用概率模型或…

Nginx+Lua+OpenResty(详解及使用)

一、 Nginx简介 Nginx是一个高性能的Web服务器和反向代理的软件。 Web服务器&#xff1a;就是运行我们web服务的容器&#xff0c;提供web功能&#xff0c;还有tomcat也提供类似的功能。 代理是软件架构和网络设计中&#xff0c;非常重要的一个概念。 二、Nginx的反向代理&…

Scrapy爬虫框架入门(豆瓣电影Top 250)

文章目录 Scrapy 官网Scrapy 文档GithubScrapy 简介项目结构爬虫实现XPath 教程创建 Scrapy 项目配置用户代理网页 dom 元素 IP 代理池IP代理池作用配置IP代理池申请IP代理池 Scrapy 官网 https://scrapy.org/ Scrapy 文档 https://docs.scrapy.org/en/latest/ Github htt…

Opencv_2_ 图像色彩空间转换

ColorInvert.h 内容如下&#xff1a; #pragma once #include <opencv.hpp> using namespace std; #include <opencv.hpp> using namespace cv; using namespace std; class ColorInvert{ public : void colorSpaceInvert(Mat&image); }; ColorInvert.cpp…

构建云原生湖仓:Apache Iceberg与Amoro的结合实践

随着大数据技术的快速发展&#xff0c;企业对数据的处理和分析需求日益增长。传统的数据仓库已逐渐无法满足现代业务对数据多样性和实时性的要求&#xff0c;这促使了数据湖和数据仓库的融合&#xff0c;即湖仓一体架构的诞生。在云原生技术的推动下&#xff0c;构建云原生湖仓…

数据库服务类--Redis--未授权访问终端Getshell

免责声明:本文仅做技术交流与学习. 目录 前提条件: windows上开启redis服务: Linux上创建&开启redis服务: 操作: 1-连接靶机redis 2-写入webshell 3-访问后门 redis--->webshell Redis未授权访问漏洞复现与利用 - 知乎 (zhihu.com) 前提条件: 端口开放(6379) 目录…

[LeetCode]—— 226——翻转二叉树

1.题目 . - 力扣&#xff08;LeetCode&#xff09; 给你一棵二叉树的根节点 root &#xff0c;翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a; 输入&#xff1a;root [4,2,7,1,3,6,9] 输出&#xff1a;[4,7,2,9,6,3,1]示例 2&#xff1a; 输入&#xff1a…