[应用相关]

如何确保某一段程序不被优化掉

[复制链接]
1682|38
手机看帖
扫描二维码
随时随地手机跟帖
rosemoore|  楼主 | 2024-2-26 11:31 | 显示全部楼层 |阅读模式
使用mdk编程,假如有一个有用的函数你定义了但是没有显式的调用,mdk在默认方式下,将会把这个函数从整个程序总删除掉,以节省ROM.
比如,你在ROM的0x00002000处定位了一个函数,假设为void test(void),然后使用函数指针来调用它:
void (*UserProgram)();          //函数指针
UserProgram = (void (*)()) (0x00002000);//定位到指定的入口地址0x00002000
(*UserProgram)();//调用test()函数
这样做的本意是调用test()函数,但编译器并不知情,它仍会按照默认的指令将test函数给整个优化掉,因为它觉得test()函数根本没有被调用,这个时候,虽然(*UserProgram)();仍会执行,但内容与初衷已经大相径庭.
能否让编译器不自动优化test这个函数?
当然有,就是使用链接器命令:--keep=section_id   此选项指定删除未使用节时不能删除的输入节。
其中 section_id 是以下项之一:
symbol 指定在删除未使用节时保留定义 symbol 的输入节。 如果 symbol 存在多个定义,则 armlink 将生成一则错误消息。
           例如,您可能使用 --keep=int_handler。若要保留定义以 _handler 结尾的符号的所有节,请使用--keep=*_handler。
object(section)指定在删除未使用节时保留 object 中的 section。 例如,若要保留vectors.o 对象的 vect 节,请使用: --      keep=vectors.o(vect)若要保留 vectors.o 对象中节名称的前三个字母是 vec 的所有节,请使用:--keep=vectors.o(vec*)
由于我的程序test()函数是单独放在一个文件里(entry.c)的,所以我在linker标签栏下的Misc controls编辑框中输入--keep=entry.o

使用特权

评论回复
Bowclad| | 2024-2-26 16:30 | 显示全部楼层
ac6是不是不能用啊

使用特权

评论回复
Henryko| | 2024-2-29 23:20 | 显示全部楼层
这个也要看编译器支不支持

使用特权

评论回复
olivem55arlowe| | 2024-3-2 07:48 | 显示全部楼层
虽然编译器优化可以提高程序的性能,但在某些情况下,你可能会需要保持代码的原始形式以便于理解和调试。

使用特权

评论回复
burgessmaggie| | 2024-3-2 18:58 | 显示全部楼层
可以使用volatile关键字声明。这告诉编译器不要对这样的变量进行优化。

使用特权

评论回复
geraldbetty| | 2024-3-3 10:45 | 显示全部楼层
如果你定义了一个函数但没有在代码中显式调用它,编译器可能会认为这个函数没有被使用而将其优化掉。为了避免这种情况,可以在程序的某个地方手动调用这个函数,即使这个调用看起来没有必要。

使用特权

评论回复
ccook11| | 2024-3-3 14:41 | 显示全部楼层
可以使用编译器指令来禁用优化。              

使用特权

评论回复
yorkbarney| | 2024-3-3 17:37 | 显示全部楼层
在某些情况下,你可以将代码放入特定的段,并确保这个段不被优化。这需要在链接器脚本中进行配置。

使用特权

评论回复
lihuami| | 2024-3-3 19:41 | 显示全部楼层
volatile关键字告诉编译器,变量的值可能会被程序之外的因素改变,因此不能对其进行优化。

使用特权

评论回复
nomomy| | 2024-3-3 22:32 | 显示全部楼层
使用链接器选项 -keep 或 --no-optimize-sections

使用特权

评论回复
vivilyly| | 2024-3-4 12:53 | 显示全部楼层
虽然这不是为了防止代码被优化,但使用断言可以确保代码在某些条件下不会执行预期之外的操作。

使用特权

评论回复
lzbf| | 2024-3-5 11:03 | 显示全部楼层
声明一个变量为volatile时,编译器会认为该变量的值可能在任何时候被外部因素更改,因此它不会对含有volatile变量的代码进行优化,确保每次访问该变量时都会实际读取或写入。

使用特权

评论回复
bestwell| | 2024-3-5 22:37 | 显示全部楼层
优化级别和选项可能会随着Keil版本的不同而有所变化,所以具体的设置可能需要根据你使用的Keil版本进行调整。

使用特权

评论回复
chenci2013| | 2024-3-6 07:57 | 显示全部楼层
在变量声明前加上volatile关键字可以告诉编译器该变量可能会被意外改变,因此编译器不应对其进行优化。

使用特权

评论回复
yangxiaor520| | 2024-3-6 08:07 | 显示全部楼层
volatile只是对变量优化起作用

使用特权

评论回复
jtracy3| | 2024-3-7 11:16 | 显示全部楼层
编译器通常提供特定的指令或选项来控制优化行为。例如,在Keil中,可以通过编译器指令或项目选项来设置不进行某些类型的优化。

使用特权

评论回复
jimmhu| | 2024-3-7 23:28 | 显示全部楼层
在中断服务例程(ISR)或异常处理代码中,即使这些代码在正常程序执行过程中不会被调用,编译器通常也会保留这些代码,因为它们可能在异常情况下被执行。

使用特权

评论回复
juliestephen| | 2024-3-10 08:24 | 显示全部楼层
在Keil uVision的编译器设置中,你也可以调整优化级别。转到“Project”菜单下的“Options for Target”或“Options for Target”对话框,然后在“C/C++”标签下找到“Optimization”选项,从中选择适当的优化级别。

使用特权

评论回复
pmp| | 2024-3-11 18:53 | 显示全部楼层
可以使用volatile关键字。这通常用于硬件寄存器或中断服务程序中的变量,因为这些变量可能会在程序的控制之外被修改。

使用特权

评论回复
primojones| | 2024-3-11 21:23 | 显示全部楼层
如果需要确保特定的代码段不被优化,可以在链接器脚本中明确指定这些段的属性,告诉链接器不要丢弃这些代码。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

49

主题

1305

帖子

2

粉丝