发新帖本帖赏金 3.00元(功能说明)我要提问
返回列表
打印
[STM32F1]

STM32芯片导致的还是C语言导致的这个灵异事件,求大神解释!

[复制链接]
楼主: 工行ATM
手机看帖
扫描二维码
随时随地手机跟帖
21
工行ATM 发表于 2016-12-8 16:40
但是。。。拆开看起来不爽。。。

不要热衷于那些花里胡哨的所谓的“技巧”。
老老实实分开写,意义要明确的多。
你非要写在一行里面,编译出来不见得比分几行写的要少。

使用特权

评论回复
22
zyj9490| | 2016-12-8 20:09 | 只看该作者
孔忆已的代码,多花几行让人看明白很难吗?还不是多学点数据结构和软件工程。

使用特权

评论回复
23
flydream0| | 2016-12-8 21:22 | 只看该作者
本帖最后由 flydream0 于 2016-12-8 22:57 编辑

问这种问题的一般是在校大学生吧。。。实际项目中要是写出这种与编译器相关的代码,会被项目领导骂死!与MCU 无关,只与编译器有关,有些编译器从左到右计算,这个符合人类的第一感觉,但大多数编译器还是从右到左计算。这种写法移植性太差!无任何意义。

使用特权

评论回复

打赏榜单

工行ATM 打赏了 0.50 元 2016-12-09
理由:受教了~

24
Dongfangyuxiao| | 2016-12-8 21:55 | 只看该作者
我向来喜欢用汇编风格编写。生怕写太多复合语句(像数学里的复合函数),编译出问题。时间长了也不好维护和理解。

使用特权

评论回复
25
lyfly_away| | 2016-12-8 21:57 | 只看该作者
仿真出来后结果是0x2211,就证明了先算右边的算式,可以反汇编看。
类似这种执行先后有不同结果的算式,最好分开写。

使用特权

评论回复
26
zhuotuzi| | 2016-12-8 22:54 | 只看该作者
这个语法上有什么灵异的,不好用的语法结构别用就最好了

使用特权

评论回复
27
戈卫东| | 2016-12-8 23:02 | 只看该作者
不想被老板打死就老老实实分开写。。。。。。。

使用特权

评论回复
28
yjmwxwx| | 2016-12-8 23:08 | 只看该作者
工行ATM 发表于 2016-12-8 17:16
再贴一段keil5的汇编代码,请能看懂的大神解释一下orz!
   333:                                         ...

把这个汇编分成三部分

0x080014C8 48C2      LDR      r0,[pc,#776]  ; @0x080017D4
0x080014CA 7801      LDRB     r1,[r0,#0x00]
0x080014CC 7800      LDRB     r0,[r0,#0x00]
0x080014CE 1C40      ADDS     r0,r0,#1
0x080014D0 4AC0      LDR      r2,[pc,#768]  ; @0x080017D4
0x080014D2 7010      STRB     r0,[r2,#0x00]
0x080014D4 48C0      LDR      r0,[pc,#768]  ; @0x080017D8
0x080014D6 5C41      LDRB     r1,[r0,r1]

从0X80017D4取一个8位分别放到R1和R0 , R0的那个加1再写回0X80017D4,  另一个R1加0X80017D8地址里面一个8位数据放到R1




0x080014D8 4610      MOV      r0,r2
0x080014DA 7802      LDRB     r2,[r0,#0x00]
0x080014DC 7800      LDRB     r0,[r0,#0x00]
0x080014DE 1C40      ADDS     r0,r0,#1
0x080014E0 4BBC      LDR      r3,[pc,#752]  ; @0x080017D4
0x080014E2 7018      STRB     r0,[r3,#0x00]
0x080014E4 48BC      LDR      r0,[pc,#752]  ; @0x080017D8
0x080014E6 5C80      LDRB     r0,[r0,r2]



从0X80017D4取出一个8位数据分别放到R2和R0,R0的那个8位加1再写回0X80017D4, 另一个R2加0X80017D8地址里面的8位数据放到R0



0x080014E8 EA412000  ORR      r0,r1,r0,LSL #8
0x080014EC 49BB      LDR      r1,[pc,#748]  ; @0x080017DC
0x080014EE 8308      STRH     r0,[r1,#0x18]
0x080014F0 E000      B        0x080014F4


R0的8位左移8位变成16位, 原来R0的8位数据放在16位数据的高8位。  前面的R1里面的8位数据放到16位数据的低8位, 然后把这个16位数据放到0X80017DC加0X18的地址里面



使用特权

评论回复

打赏榜单

工行ATM 打赏了 1.00 元 2016-12-09
理由:从分析看是最后一步出了问题,编译器的问题

29
小鱼儿1045| | 2016-12-8 23:57 | 只看该作者
楼主为什么不分开写,我一般都是分开计算,这样程序易读,还不容易出错!

使用特权

评论回复
30
chunk| | 2016-12-9 00:56 | 只看该作者
不同的编译器对这种写法的语句有不同的结果。

所以,避免这种写法最好。

使用特权

评论回复
31
wxl_user| | 2016-12-9 08:14 | 只看该作者
看汇编代码,及ORR指令说明,MDK编译器会给出告警的。

无标题.png (299.77 KB )

无标题.png

使用特权

评论回复
32
工行ATM|  楼主 | 2016-12-9 08:35 | 只看该作者
感谢大家的回复和建议!orz
这个问题确实是由于编译器引起的,身边的大神换了一个编译器编译出来的结果是0x1122,初步确定是自加运算 ++ 引起的这个问题,建议每行代码中最多用一次++,现在就去改代码,再次感谢各位大神~

使用特权

评论回复
33
工行ATM|  楼主 | 2016-12-9 08:57 | 只看该作者
@mmuuss586  结帖

是这样结帖吧。。

使用特权

评论回复
34
NE5532| | 2016-12-9 09:06 | 只看该作者
工行ATM 发表于 2016-12-8 16:40
但是。。。拆开看起来不爽。。。

要爽就去撸吧,搞开发不会带给你快感,谁爽谁给钱,这个道理够简单了吧。你去上班,写代码,写爽了,应该你给老板开工资??

使用特权

评论回复
评分
参与人数 1威望 +4 收起 理由
zh_sl + 4 谁爽谁给钱,很给力
35
ddllxxrr| | 2016-12-9 09:20 | 只看该作者
肯定是楼主的算式有问题,如果KEIL或C语言编译器的问题,那就不能用了

使用特权

评论回复
36
七颗咖啡豆| | 2016-12-9 09:33 | 只看该作者
老工程师都不会这么搞,这种技巧不要用。
第一不能提高CPU效率,第二不能节约ram使用。
写程序不是玩语言技巧,玩的是系统架构的清晰和稳定性。

使用特权

评论回复
37
hzt1234hf| | 2016-12-9 09:33 | 只看该作者
看下汇编代码啊,看看编译器怎么解释的

使用特权

评论回复
38
daen_lin| | 2016-12-9 09:35 | 只看该作者
我竟然看完了所有的评论,我想说这种有歧义的代码不应该出现在工程中。代码是要高效,但更要易懂、易维护。可能你合成一句和分成两句占用资源是差不多的。

使用特权

评论回复
39
john_lee| | 2016-12-9 10:09 | 只看该作者
我教你一个正规的方法:你的 MCU 是 Cortex-M3,你应该直接把两个字节的数据“一次”取出,然后使用 CMSIS 提供的字节序反转函数:__REV16。这个函数是编译器的 builtin (内置) 函数,生成的 CPU 指令最少就只有一条。
以你的表达式为例:
result = __REV16 (((uint16_t*)str)[counter]); // 这里只有一次读取数据
counter += sizeof (uint16_t);

使用特权

评论回复
40
xiaofei558008| | 2016-12-9 10:18 | 只看该作者
数组是往下生长的;和C语言和单片机都没关系;

使用特权

评论回复
发新帖 本帖赏金 3.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则