keil把c语言函数转成汇编

news2025/1/17 3:12:55

汇编可以让开发人员从根源上理解程序的运行逻辑,本文介绍如何在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这行删掉。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Post请求中常见的Content-Type类型

Post请求中常见的Content-Type类型的结构 (1)application/x-www-form-urlencoded 这是浏览器原生的form表单类型,或者说是表单默认的类型。 下面是一个请求实例: 请求报文: 可以看得出,post将请求参数以k…

python学习笔记(常用方法)

方法1:字符串中元素大小写 1.name.title():首字母大写 2.name.upper():全部大写 3.name.lower():全部小写 # 字母大小写 nametian yang print(name.title()) # 首字母大写 print(name.upper()) # 全部大写 print(name.lower()) # 全部小写 Tian Yang TIAN YANG tia…

银行押款车远程监控系统的实际需求与特点

随着金融行业的快速发展,银行押款车的安全性问题日益受到重视。传统的押款车监控方式已经无法满足现代安全管理的需求,因此,一种结合先进技术的远程监控系统应运而生。本文旨在探讨在运钞车上安装车载摄像机和集成有GPS、无线4G网络传输模块的…

温湿度上传数据到云平台机智云

esp8266使用前的操作 固件修改 如果之前添加过 想要再次添加就把解压的文件夹删了 在重新解压一个 硬件连线 需要两个CH340(USB转TTL模块) 一个CH340模块的TX和RX分别于esp8266的RX和TX连接 3V3和GND也连接 另一个模块只需要连接一根线 就是GND连…

运筹系列91:vrp算法包PyVRP

1. 介绍 PyVRP使用HGS(hybrid genetic search)算法求解VRP类问题。在benchmark上的评测结果如下,看起来还不错: 2. 使用例子 2.1 CVRP COORDS [(456, 320), # location 0 - the depot(228, 0), # location 1(912, 0), …

Wireshark安装教程

一、下载 地址:https://www.wireshark.org/download.html打开网址后,点击相应的版本下载: 二、安装 下载完成后双击文件开始安装 点击Next 点击Noted 点击Next 点击Next 点击Next 可以点击Browse更改安装路径,默认…

Python实时聊天机器人框架之errbot使用详解

概要 在现代软件开发中,即时通讯和自动化任务的需求越来越重要。Python的Errbot库是一个强大的实时聊天机器人框架,可以帮助开发者快速构建自定义的聊天机器人应用,提供了丰富的特性和灵活的扩展能力。 安装 Errbot的安装非常简单,可以通过pip工具进行安装: pip instal…

力扣【LeetCode】258:各位相加

🎁个人主页:我们的五年 🔍系列专栏:每日一练 🌷追光的人,终会万丈光芒 前言: 【LeetCode】真的是一个好网站呀,上面的题目的太经典了,提供的方法也很很多,非…

抖店怎么高效选品?99%卖家都容易忽略的选品秘密

大家好,我是电商花花。 选品是我们做抖店商家最为担心的问题,如果选品选的不多,就很容易影响我们店铺的销量和转化,所以我们在做店的时候一定要学会高效选品。 今天花花分享一招高效选品的方法,或许大家都注意到&…

remote: HTTP Basic: Access deniedfatal: Authentication failed for

$ git push -u origin main remote: HTTP Basic: Access denied fatal: Authentication failed for https://gitcode.com/edenl/GD32E350_hid_keyboard.git/ 使用访问令牌做为密码登录即可。

uniapp小程序订阅通知

服务 开通订阅服务 const tmplIds ref([tsdasdadasdfgdrtwexQHdEsjZV])//换成自己的 function confirm(){uni.requestSubscribeMessage({tmplIds: tmplIds.value,success: (res) > {// console.log(res)let auth_notice res[tmplIds.value[0]] accept ? 1 : 2 //1是接…

WPF 资源基础

动态资源/静态资源 UI代码 <Window x:Class"WpfApp1.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/ex…

Kafka 3.x.x 入门到精通(08)——对标尚硅谷Kafka教程

Kafka 3.x.x 入门到精通&#xff08;08&#xff09;——对标尚硅谷Kafka教程 5. Kafka优化5.1 资源配置5.1.1 操作系统5.1.2 磁盘选择5.1.3 网络带宽5.1.4 内存配置5.1.5 CPU选择 5.2 集群容错5.2.1 副本分配策略5.2.2 故障转移方案5.2.3 数据备份与恢复 5.3 参数配置优化5.4 数…

西安交通大学 915 备考常见误区

看到助教在 915 全程班群里给同学们解答问题&#xff0c;我也是感触颇深&#xff0c;想起来我当年自身的一个备考情况。接下来结合我自身情况给同学们分析一下&#xff0c;为什么有的同学基础一般&#xff0c;最后分数却很高&#xff0c;有的同学基础很好&#xff0c;分数却一般…

CC软件防火墙和WEB应用防火墙哪个好

本文将从CC软件防火墙的定义、原理、功能以及应用方面进行全面探讨&#xff0c;旨在加深对CC软件防火墙的理解&#xff0c;并推动网络安全意识的普及。以及WEB应用防火墙二者之间的对比。让用户更了解两个形态产品并作出选择。 第一部分&#xff1a;CC软件防火墙的定义和原理 …

探索UTONMOS《神念无界-源起山海》元宇宙游戏的奇幻世界

在科技的前沿&#xff0c;元宇宙游戏如同一扇神秘的大门&#xff0c;缓缓开启&#xff0c;引领我们进入一个前所未有的奇幻世界。 UTONMOS《神念无界-源起山海》元宇宙游戏是数字世界的巅峰之作&#xff0c;它打破了现实与虚拟的界限&#xff0c;让玩家能够身临其境地体验各种奇…

新开的拼多多店铺怎么运营

今天给大家分享一下如何在拼多多平台上开设并运营一家店铺。不管你是创业者还是小型商家&#xff0c;相信这个话题都会对你有所帮助。 拼多多新店需要做些推广提高店铺权重 新店用3an推客做推广比较好 3an推客是给商家提供的营销工具&#xff0c;3an推客CPS推广模式由商家自主…

C++笔试强训day7

目录 1.字符串中找出连续最长的数字串 2.岛屿数量 3.拼三角 1.字符串中找出连续最长的数字串 链接 我的思路很简洁&#xff0c;就是双指针遍历&#xff0c;然后不断更新左位置left和右位置right和长度len。 然后我写代码的时候代码思路没跟上原本思路&#xff0c;直接把所有…

实验七 智能手机互联网程序设计(微信程序方向)实验报告

请编写一个用户登录界面&#xff0c;提示输入账号和密码进行登录&#xff0c;要求在输入后登陆框显示为绿色&#xff1b; 二、实验步骤与结果&#xff08;给出对应的代码或运行结果截图&#xff09; index.wxml <view class"content"> <view class"a…

链表与模拟LinkedList的实现

1. ArrayList的缺陷 ArrayList底层使用数组来存储元素 由于其底层是一段连续空间&#xff0c;当在ArrayList任意位置插入或者删除元素时&#xff0c;就需要将后序元素整体往前或者往后 搬移&#xff0c;时间复杂度为O(n)&#xff0c;效率比较低。因此ArrayList不适合做任意位…