当前位置: 首页 > 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文件&…...

【计算机网络】计算机网络

目录一、概述计算机网络体系结构二、应用层DNS应用文件传输应用DHCP 应用电子邮件应用Web应用当访问一个网页的时候&#xff0c;都会发生什么三、传输层UDP 和 TCP 的特点UDP 首部格式TCP 首部格式TCP 的三次握手TCP 的四次挥手TCP 流量控制TCP 拥塞控制三、网络层IP 数据报格式…...

【java web篇】项目管理构建工具Maven简介以及安装配置

&#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是阿牛&#xff0c;全栈领域优质创作者。&#x1f61c;&#x1f4dd; 个人主页&#xff1a;馆主阿牛&#x1f525;&#x1f389; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4d…...

springboot笔记

微服务架构 微服务是一种架构风格&#xff0c;开发构建应用的时候把应用的业务构建成一个个的小服务&#xff08;这就类似于把我们的应用程序构建成了一个个小小的盒子&#xff0c;它们在一个大的容器中运行&#xff0c;这种一个个的小盒子我们把它叫做服务&#xff09;&#…...

【多线程与高并发】- 浅谈volatile

浅谈volatile简介JMM概述volatile的特性1、可见性举个例子总结2、无法保证原子性举个例子分析使用volatile对原子性测试使用锁的机制总结3、禁止指令重排什么是指令重排序重排序怎么提高执行速度重排序的问题所在volatile禁止指令重排序内存屏障(Memory Barrier)作用volatile内…...

avro格式详解

【Avro介绍】Apache Avro是hadoop中的一个子项目&#xff0c;也是一个数据序列化系统&#xff0c;其数据最终以二进制格式&#xff0c;采用行式存储的方式进行存储。Avro提供了&#xff1a;丰富的数据结构可压缩、快速的二进制数据格式一个用来存储持久化数据的容器文件远程过程…...

【涨薪技术】0到1学会性能测试 —— LR录制回放事务检查点

前言 上一次推文我们分享了性能测试分类和应用领域&#xff0c;今天带大家学习性能测试工作原理、事务、检查点&#xff01;后续文章都会系统分享干货&#xff0c;带大家从0到1学会性能测试&#xff0c;另外还有教程等同步资料&#xff0c;文末免费获取~ 01、LR工作原理 通常…...

卡尔曼滤波原理及代码实战

目录简介1.原理介绍场景假设(1).下一时刻的状态(2).增加系统的内部控制(3).考虑运动系统外部的影响(4).后验估计&#xff1a;预测结果与观测结果的融合卡尔曼增益K2.卡尔曼滤波计算过程(1).预测阶段&#xff08;先验估计阶段&#xff09;(2).更新阶段&#xff08;后验估计阶段&…...

Jmeter使用教程

目录一&#xff0c;简介二&#xff0c;Jmeter安装1&#xff0c;下载2&#xff0c;安装三&#xff0c;创建测试1&#xff0c;创建线程组2&#xff0c;创建HTTP请求默认值3&#xff0c;创建HTTP请求4&#xff0c;添加HTTP请求头5&#xff0c;添加断言6&#xff0c;添加查看结果树…...

论文笔记|固定效应的解释和使用

DeHaan E. Using and interpreting fixed effects models[J]. Available at SSRN 3699777, 2021. 虽然固定效应在金融经济学研究中无处不在&#xff0c;但许多研究人员对作用的了解有限。这篇论文解释了固定效应如何消除遗漏变量偏差并影响标准误差&#xff0c;并讨论了使用固…...

数据集市与数据仓库的区别

数据仓库是企业级的&#xff0c;能为整个企业各个部门的运作提供决策支持&#xff1b;而数据集市则是部门级的&#xff0c;一般只能为某个局部范围内的管理人员服务&#xff0c;因此也称之为部门级数据仓库。 1、两种数据集市结构 数据集市按数据的来源分为以下两种 &#x…...

Golang学习Day3

&#x1f60b; 大家好&#xff0c;我是YAy_17&#xff0c;是一枚爱好网安的小白。 本人水平有限&#xff0c;欢迎各位师傅指点&#xff0c;欢迎关注 &#x1f601;&#xff0c;一起学习 &#x1f497; &#xff0c;一起进步 ⭐ 。 ⭐ 此后如竟没有炬火&#xff0c;我便是唯一的…...

Python并发编程-事件驱动模型

一、事件驱动模型介绍 1、传统的编程模式 例如&#xff1a;线性模式大致流程 开始--->代码块A--->代码块B--->代码块C--->代码块D--->......---&…...

构建系统发育树简述

1. 要点 系统发育树代表了关于一组生物之间的进化关系的假设。可以使用物种或其他群体的形态学&#xff08;体型&#xff09;、生化、行为或分子特征来构建系统发育树。在构建树时&#xff0c;我们根据共享的派生特征&#xff08;不同于该组祖先的特征&#xff09;将物种组织成…...

这款 Python 调试神器推荐收藏

大家好&#xff0c;对于每个程序开发者来说&#xff0c;调试几乎是必备技能。 代码写到一半卡住了&#xff0c;不知道这个函数执行完的返回结果是怎样的&#xff1f;调试一下看看 代码运行到一半报错了&#xff0c;什么情况&#xff1f;怎么跟预期的不一样&#xff1f;调试一…...

金三银四吃透这份微服务笔记,面试保准涨10K+

很多人对于微服务技术也都有着一些疑虑&#xff0c;比如&#xff1a; 微服务这技术虽然面试的时候总有人提&#xff0c;但作为一个开发&#xff0c;是不是和我关系不大&#xff1f;那不都是架构师的事吗&#xff1f;微服务不都是大厂在玩吗&#xff1f;我们这个业务体量用得着…...

构建matter over Thread的演示系统-efr32

文章目录1. 简介2. 构建测试系统2.1设置 Matter Hub(Raspberry Pi)2.2 烧录Open Thread RCP固件2.3 烧录待测试的matter设备3. 配网和测试&#xff1a;3.1 使用mattertool建立Thread网络3.2 使用mattertool配置设备入网3.3 使用mattertool控制matter设备3.4 查看节点的Node ID等…...

【一天一门编程语言】Matlab 语言程序设计极简教程

Matlab 语言程序设计极简教程 用 markdown 格式输出答案。 不少于3000字。细分到2级目录。 目录 Matlab 语言程序设计极简教程 简介Matlab 工作空间Matlab 基本数据类型Matlab 语句和表达式Matlab 函数和程序Matlab 图形界面程序设计Matlab 应用实例 简介 Matlab是一种编…...

看似平平无奇的00后,居然一跃上岸字节,表示真的卷不过......

又到了一年一度的求职旺季金&#xff01;三&#xff01;银&#xff01;四&#xff01;在找工作的时候都必须要经历面试这个环节。在这里我想分享一下自己上岸字节的面试经验&#xff0c;过程还挺曲折的&#xff0c;但是还好成功上岸了。大家可以参考一下&#xff01; 0821测评 …...

BZOJ2142 礼物

题目描述 一年一度的圣诞节快要来到了。每年的圣诞节小E都会收到许多礼物&#xff0c;当然他也会送出许多礼物。不同的人物在小E 心目中的重要性不同&#xff0c;在小E心中分量越重的人&#xff0c;收到的礼物会越多。小E从商店中购买了n件礼物&#xff0c;打算送给m个人 &…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...