[STM32F1] 请教一条语句i = (i >> 6) << 6;

[复制链接]
2296|26
 楼主| cooldog123pp 发表于 2018-9-13 10:11 | 显示全部楼层
knight_21ic 发表于 2018-9-12 22:31
这种技巧不学也罢

为啥,就是写了别人不理解。同样清零的方法有很多 是吧,大神难道这么写还有别的含义在里面吗
 楼主| cooldog123pp 发表于 2018-9-13 10:12 | 显示全部楼层
linqing171 发表于 2018-9-13 09:26
在ARM下,充分利用其CPU内部的桶形移位寄存器,两次移位把低6位清零。
而在8051下,用 and 0xC0只有一条指 ...

受教了,原来还有这种说法,看来学习的不是很深入,老大你的意思就是好程序执行的效率有关是吧
kingkits 发表于 2018-9-13 15:44 | 显示全部楼层
这行代码只做了一次数据总线读和写,其他的都在主寄存器里,代码量很短,占用寄存器一个,在很多情况下都有用。
如果移位操作只需要一个指令周期,那么只需要运算2个周期就完成了。
而且,不用判断数据长度(也许适合在宏定义中使用)
不过,除了极端需要速度优化的情况,其实用途不大,而且看起来很难理解。不推荐大家这样用。不如直接用 (&0xFFFFFFC0) 之类的操作 看得更清晰
john_lee 发表于 2018-9-13 16:41 | 显示全部楼层
linqing171 发表于 2018-9-13 09:26
在ARM下,充分利用其CPU内部的桶形移位寄存器,两次移位把低6位清零。
而在8051下,用 and 0xC0只有一条指 ...

想当然了,其实这个操作并不需要移位,移位的开销反而更高。
以下三种写法:
  1. i = i >> 6 << 6;
  1. i = i / 64 * 64;
  1. i &= ~63;

优化编译结果都是一样的,在 arm 指令集中只要一条指令:
  1. bic        r0, r0, #63

在 thumb2 指令集中也是一条指令:
  1. bic.w        r0, r0, #63

在 thumb 指令集中要差一些,要两条指令:
  1. movs        r3, #63
  2. bics        r0, r3
linqing171 发表于 2018-9-13 22:04 | 显示全部楼层
john_lee 发表于 2018-9-13 16:41
想当然了,其实这个操作并不需要移位,移位的开销反而更高。
以下三种写法:

我确实没有试。
bic指令确实能更省。但是bic指令的立即数最大只到255。到65535的时候(32位转16位或者转8位的时候),生成的汇编里面是用两条移位指令的。

thumb的这个多用了一个r3寄存器.
greatbin 发表于 2018-9-13 22:50 | 显示全部楼层
knight_21ic 发表于 2018-9-12 22:31
这种技巧不学也罢

这算是技巧?
linqing171 发表于 2018-9-13 22:59 | 显示全部楼层
测了一下,Thumb(ARM7 TDMI)情况下,有移位代码的生成。移位也是两条thumb指令,只使用一个寄存器。


移位测试.png
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部