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

51单片机入门 - SDCC / Keil_C51 会让没有调用的函数参与编译吗?

Small Device C Compiler(SDCC)是一款免费 C 编译器,适用于 8 位微控制器。

不想看测试过程的话可以直接划到最下面看结论:)

关于软硬件环境的信息:

  • Windows 10
  • STC89C52RC
  • SDCC (构建HEX文件)
  • stcgal 1.6 (向STC单片机烧录)

修改代码中的数值会改变编译后的结果

显然,在我们修改一些 C 语言代码的时候,编译后的二进制文件也可能发生改变,尤其是一些关键的数值,在 51 单片机开发中,C 代码会编译成 .HEX 文件,然后烧录到单片机。

下面用 SDCC 编译这个示例程序来演示:

  1. 这是个选择一位数码管并使其亮起的程序:
    #include <8051.h>#define decoder_in_1 P2_2 // 译码器的 3 位输入,用于位选
    #define decoder_in_2 P2_3
    #define decoder_in_3 P2_4
    #define NUMBER P0unsigned int LED_MAP[11] = {0x3f, 0x6, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x7, 0x7f, 0x6f};void send_to_decoder(unsigned int position) {  // position: 1 ~ 8 position--;                          // position: 0 ~ 7 (000 ~ 111)decoder_in_1 = position & 1;         // low    bit of position (position & 001)decoder_in_2 = position & 2;         // middle bit of position (position & 010)decoder_in_3 = position & 4;         // high   bit of position (position & 100)
    }void main() {send_to_decoder(1);  // 位选:选择第 1 位数码管亮起NUMBER = LED_MAP[6]; // 段选:数码管显示数字 6
    }
    
  2. 改变了上面代码的位选,选择第 2 位数码管亮起:
    #include <8051.h>#define decoder_in_1 P2_2 // 译码器的 3 位输入,用于位选
    #define decoder_in_2 P2_3
    #define decoder_in_3 P2_4
    #define NUMBER P0unsigned int LED_MAP[11] = {0x3f, 0x6, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x7, 0x7f, 0x6f};void send_to_decoder(unsigned int position) {  // position: 1 ~ 8 position--;                          // position: 0 ~ 7 (000 ~ 111)decoder_in_1 = position & 1;         // low    bit of position (position & 001)decoder_in_2 = position & 2;         // middle bit of position (position & 010)decoder_in_3 = position & 4;         // high   bit of position (position & 100)
    }void main() {send_to_decoder(2);  // 位选:选择第 2 位数码管亮起NUMBER = LED_MAP[6]; // 段选:数码管显示数字 6
    }
    

对比它们生成的 HEX 文件的区别:

slightwind@ubuntu:/xxx/diff$ diff 1.hex 2.hex
9c9
< :0C00BE00A42290000112009E85148022F4
---
> :0C00BE00A42290000212009E85148022F3

可以看到第 9 行出现了区别。

头文件中没有被调用的函数

把数组 LED_MAP 放到头文件中,再从主函数中调用,头文件还包含了程序没有调用过的 sleep()
swutil.h

#ifndef __SWUTIL_H__
#define __SWUTIL_H__unsigned int LED_MAP[11] = {0x3f, 0x6, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x7, 0x7f, 0x6f};void sleep(unsigned int n); // sleep n (ms)#endif

swutil.c

void sleep(unsigned int n){unsigned char i, j;while (n--){i = 2;j = 239;do{while(--j);}while(--i);}
}

main.c

#include <8051.h>
#include "swutil.h"#define decoder_in_1 P2_2 // 译码器的 3 位输入,用于位选
#define decoder_in_2 P2_3
#define decoder_in_3 P2_4
#define NUMBER P0void send_to_decoder(unsigned int position) {  // position: 1 ~ 8 position--;                          // position: 0 ~ 7 (000 ~ 111)decoder_in_1 = position & 1;         // low    bit of position (position & 001)decoder_in_2 = position & 2;         // middle bit of position (position & 010)decoder_in_3 = position & 4;         // high   bit of position (position & 100)
}void main() {send_to_decoder(1);  // 位选:选择第 1 位数码管亮起NUMBER = LED_MAP[6]; // 段选:数码管显示数字 6
}

这时使用 SDCC 编译后生成的 HEX 文件和前面第一个实例代码生成的 HEX 文件完全一致,说明没有额外的函数参与了编译,也就是说尽管导入了比较复杂的头文件,编译器也只会让调用过的函数参与编译。

主文件中没有调用的函数

下面这个程序在前面第一个实例代码的基础上额外定义了 sleep() 函数,但是没有调用:

#include <8051.h>#define decoder_in_1 P2_2 // 译码器的 3 位输入,用于位选
#define decoder_in_2 P2_3
#define decoder_in_3 P2_4
#define NUMBER P0unsigned int LED_MAP[11] = {0x3f, 0x6, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x7, 0x7f, 0x6f};void send_to_decoder(unsigned int position) {  // position: 1 ~ 8 position--;                          // position: 0 ~ 7 (000 ~ 111)decoder_in_1 = position & 1;         // low    bit of position (position & 001)decoder_in_2 = position & 2;         // middle bit of position (position & 010)decoder_in_3 = position & 4;         // high   bit of position (position & 100)
}void sleep(unsigned int n){unsigned char i, j;while (n--){i = 2;j = 239;do{while(--j);}while(--i);}
}void main() {send_to_decoder(1);  // 位选:选择第 1 位数码管亮起NUMBER = LED_MAP[6]; // 段选:数码管显示数字 6
}

同样是用 SDCC 编译,diff 一下和第一个程序生成的 HEX 的区别,可以发现文件变大了,也有很多不一样的地方。

slightwind@ubuntu:/xxx/diff$ diff 1.hex 4.hex
6c6
< :030003000200C038
---
> :030003000200DC1C
9c9,11
< :0C00BE00A42290000112009E85148022F4
---
> :1000BE00A422AE82AF838E048F051EBEFF011FECFD
> :1000CE004D600A7DEF7C02DDFEDCFC80E9229000B3
> :0800DE000112009E851480222E
11c13
< :100013007900E94400601B7A009000CE780175A056
---
> :100013007900E94400601B7A009000EA780175A03A
17,18c19,20
< :0D00060075811D1200CAE58260030200032F
< :0400CA007582002219
---
> :0D00060075811D1200E6E582600302000313
> :0400E60075820022FD

所以在 main.c 中定义的函数,即使没有调用,也会参与 HEX 文件的构建。

在Keil_C51编译器上的测试

另外,我还将编译器换成了 Keil_C51 进行了一遍上述的测试,发现不管是包含的头文件中的函数,还是 main.c 中定义的函数,只要没有调用,都不会参与到编译中1,这样有利于生成更小的 HEX 文件。

结论

在 SDCC 中,使用的头文件中声明的函数,没有调用的话是不会参与编译的,但是在 main.c 里面直接定义的函数,尽管没有调用也是会参与编译的。
以这个简单的例子看来,在编译优化方面还是 Keil 做的更专业一些,不过 SDCC 胜在免费,是不想使用付费/破解软件时的一个不错的替代品。


  1. 这只是从上面这个简单的示例程序中表现出来的现象得到的结论,编译器的实现和优化工作非常复杂,在其他情况下可能表现出不同的结果。 ↩︎

相关文章:

51单片机入门 - SDCC / Keil_C51 会让没有调用的函数参与编译吗?

Small Device C Compiler&#xff08;SDCC&#xff09;是一款免费 C 编译器&#xff0c;适用于 8 位微控制器。 不想看测试过程的话可以直接划到最下面看结论&#xff1a;&#xff09; 关于软硬件环境的信息&#xff1a; Windows 10STC89C52RCSDCC &#xff08;构建HEX文件&…...

OpenCV只含基本图像模块编译

编译OpenCV4.5.5只含基本图像模块&#xff0c;环境为Windows10 x64CMake3.23.3VS2019。默认编译选项编译得到的OpenCV库往往大几百MB甚至上GB&#xff0c;本文配置下编译得到的库压缩后得到的zip包大小仅6.25MB&#xff0c;适合使用OpenCV基本图像功能模块的项目移植而不牵涉其…...

Java实现阴历日历表(附带星座)

准备工作 1.无敌外挂(GitHub直达源码) Nobb 直击灵魂 https://github.com/xuyishanBD/Java_create_calendar.git2.maven配置(如果没有走上面的捷径) <dependencies><dependency><groupId>net.sourceforge.javacsv</groupId><artifactId>javac…...

Python入门之最基础

Python入门之最基础 IDLE有两种模式&#xff0c;一种是交互模式&#xff0c;通俗讲就是写一个代码&#xff0c;会得到相应的反馈&#xff0c;另一种为编辑模式. 注意事项&#xff1a; 标点符号一定要用英文符号 要注意缩进 dir(builtins)可以看到python所有的内置函数&#…...

浏览器缓存策略

先走强缓存&#xff0c;再走协商缓存 强缓存 不发送请求&#xff0c;直接使用缓存的内容 状态码200 当前会话没有关闭的话就是走memory cache&#xff0c;否则就是disk cache 由响应头的 Pragma&#xff08;逐渐废弃&#xff0c;优先级最高&#xff09;&#xff0c;catch-…...

高清无码的MP4如何采集?python带你保存~

前言 大家早好、午好、晚好吖 ❤ ~ 又是我,我又来采集小姐姐啦~ 这次我们采集的网站是(看下图): 本文所有模块\环境\源码\教程皆可点击文章下方名片获取此处跳转 话不多少,我们赶快开始吧~ 第三方模块: requests >>> pip install requests 如果安装python第三方模块…...

python+pytest接口自动化(1)-接口测试基础

接口定义一般我们所说的接口即API&#xff0c;那什么又是API呢&#xff0c;百度给的定义如下&#xff1a;API&#xff08;Application Programming Interface&#xff0c;应用程序接口&#xff09;是一些预先定义的接口&#xff08;如函数、HTTP接口&#xff09;&#xff0c;或…...

go单元测试

接着上一篇中的go module创建项目calc为例&#xff0c;在simplemath包中&#xff0c;是使用在命令行中使用交互式的方式进行测试&#xff0c;现在可以为这几个函数实现单元测试&#xff0c; go test&#xff0c;这个测试工具来自于 Go 官方的 gc 工具链。 运行 go test 命令将执…...

Mybatis之一级缓存二级缓存

介绍 缓存&#xff0c;就是将经常访问的数据&#xff0c;放到内存中&#xff0c;减少对数据库的访问&#xff0c;提高查询速度。Mybatis中也有缓存的概念&#xff0c;分为一级缓存和二级缓存。 一级缓存 一级缓存是Mybatis中SqlSession对象的缓存。当我们执行查询以后&#x…...

人脸考勤机项目

文章内容如下&#xff1a; 1&#xff09;项目简介 2&#xff09;开发环境和使用的技术知识 3&#xff09;功能实现 4&#xff09;项目源码 一。项目简介 此项目是基于HOG和Dlib开发的一套实时无感考勤系统。首先是待考勤人员的个人信息录入。然后在过道或者入口处装置人脸…...

Python编程自动化办公案例(3)

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.前几章代码 1.获取到第一题的选项单元格 2.实现批量获取文件 二. 批…...

Linux-MYSQL 登录数据库(命令行,图形化) 及 远程登录

命令行登录 &#xff1a;mysql 命令登录数据库语法 &#xff1a; mysql -u用户名 -p密码 -h 连接的数据库服务器的ip [-D] 数据库名 -p 端口注 &#xff1a; 上面的 mysql 命令是指的是 客户端的指令 ~&#xff01;&#xff01;-h &#xff1a; 指的就是 连接数据库服务器的 ip…...

electron网络环境在线/离线事件探测

electron判断网络环境问题&#xff0c;可以说在任何桌面应用都可以使用到&#xff0c;处理方式有很多种&#xff0c;我介绍几种办法第一种HTML5 API navigator.onLine&#xff1a;官方案例给的&#xff0c;这边为直接贴出地址了&#xff0c;有兴趣的同学可自行查看https://www.…...

UE 项目导航数据生成配置

WP构建及常规构建操作WP构建方式 &#xff1a;https://docs.unrealengine.com/5.0/zh-CN/world-partitioned-navigation-mesh/常规构建方式针对WP的构建方式特殊配置项关闭就好&#xff1a;取消勾选RecastNavMesh-XXX下的IsWorldPartitioned执行n.bNavMeshAllowPartitionedBuil…...

494.目标和

1. 回溯算法 这题和之前做的那些排列、组合的回溯稍微有些不同&#xff0c;你不需要每次选数据时都是for遍历去选择&#xff0c;很明显这是顺序选择的 比如 数组[0,1]&#xff0c;target1&#xff1b; 递归数组&#xff0c;每个元素都 或者 - &#xff0c;然后取最后结果为0…...

滑台模组的应用有哪些?

在自动化生产中&#xff0c;我们常常会看到滑台模组的身影&#xff0c;那么&#xff0c;滑台模组究竟在自动化生产设备中起着怎样的作用呢&#xff1f; 简单点说&#xff0c;滑台模组由滑块、滚珠丝杆、导轨、主体等其它传动零件组成的自动化晋级单元&#xff0c;经过各单元的组…...

CS224W课程学习笔记(四):node2vec算法原理与说明

引言 什么是图嵌入&#xff1f; 我想从上节的deepwalk中已经有一个十分完整的轮廓了&#xff0c;这里引出deepwalk论文中的一张很形象的图&#xff08;当然&#xff0c;上节的一些实战演练&#xff0c;也将这种嵌入关系进行了模拟与可视化&#xff0c;前文为&#xff1a;&…...

扩展lucas定理

前置知识&#xff1a; lucas定理中国剩余定理 介绍 当正整数n,mn,mn,m很大&#xff0c;且质数ppp较小的时候&#xff0c;要求CnmC_n^mCnm​对ppp取模后的值&#xff0c;可以用lucas定理。 但如果ppp不是质数&#xff0c;那该怎么办呢&#xff1f;如果mmm较小&#xff0c;则…...

医疗影像工具LEADTOOLS 入门教程: 从 PDF 中提取附件 - 控制台 C#

LEADTOOLS 是一个综合工具包的集合&#xff0c;用于将识别、文档、医疗、成像和多媒体技术整合到桌面、服务器、平板电脑、网络和移动解决方案中&#xff0c;是一项企业级文档自动化解决方案&#xff0c;有捕捉&#xff0c;OCR&#xff0c;OMR&#xff0c;表单识别和处理&#…...

【LVGL】学习笔记--(1)Keil中嵌入式系统移植LVGL

一 LVGL简介最近emwin用的比较烦躁&#xff0c;同时被LVGL酷炫的界面吸引到了&#xff0c;所以准备换用LVGL试试水。LVGL(轻量级和通用图形库)是一个免费和开源的图形库&#xff0c;它提供了创建嵌入式GUI所需的一切&#xff0c;具有易于使用的图形元素&#xff0c;美丽的视觉效…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

招商蛇口 | 执笔CID,启幕低密生活新境

作为中国城市生长的力量&#xff0c;招商蛇口以“美好生活承载者”为使命&#xff0c;深耕全球111座城市&#xff0c;以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子&#xff0c;招商蛇口始终与城市发展同频共振&#xff0c;以建筑诠释对土地与生活的…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...