发新帖我要提问
12
返回列表
打印
[STM32F1]

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

[复制链接]
楼主: cooldog123pp
手机看帖
扫描二维码
随时随地手机跟帖
21
cooldog123pp|  楼主 | 2018-9-13 10:11 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
knight_21ic 发表于 2018-9-12 22:31
这种技巧不学也罢

为啥,就是写了别人不理解。同样清零的方法有很多 是吧,大神难道这么写还有别的含义在里面吗

使用特权

评论回复
22
cooldog123pp|  楼主 | 2018-9-13 10:12 | 只看该作者
linqing171 发表于 2018-9-13 09:26
在ARM下,充分利用其CPU内部的桶形移位寄存器,两次移位把低6位清零。
而在8051下,用 and 0xC0只有一条指 ...

受教了,原来还有这种说法,看来学习的不是很深入,老大你的意思就是好程序执行的效率有关是吧

使用特权

评论回复
23
kingkits| | 2018-9-13 15:44 | 只看该作者
这行代码只做了一次数据总线读和写,其他的都在主寄存器里,代码量很短,占用寄存器一个,在很多情况下都有用。
如果移位操作只需要一个指令周期,那么只需要运算2个周期就完成了。
而且,不用判断数据长度(也许适合在宏定义中使用)
不过,除了极端需要速度优化的情况,其实用途不大,而且看起来很难理解。不推荐大家这样用。不如直接用 (&0xFFFFFFC0) 之类的操作 看得更清晰

使用特权

评论回复
24
john_lee| | 2018-9-13 16:41 | 只看该作者
linqing171 发表于 2018-9-13 09:26
在ARM下,充分利用其CPU内部的桶形移位寄存器,两次移位把低6位清零。
而在8051下,用 and 0xC0只有一条指 ...

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

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

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

在 thumb 指令集中要差一些,要两条指令:
movs        r3, #63
bics        r0, r3

使用特权

评论回复
25
linqing171| | 2018-9-13 22:04 | 只看该作者
john_lee 发表于 2018-9-13 16:41
想当然了,其实这个操作并不需要移位,移位的开销反而更高。
以下三种写法:

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

thumb的这个多用了一个r3寄存器.

使用特权

评论回复
26
greatbin| | 2018-9-13 22:50 | 只看该作者
knight_21ic 发表于 2018-9-12 22:31
这种技巧不学也罢

这算是技巧?

使用特权

评论回复
27
linqing171| | 2018-9-13 22:59 | 只看该作者
测了一下,Thumb(ARM7 TDMI)情况下,有移位代码的生成。移位也是两条thumb指令,只使用一个寄存器。



使用特权

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

本版积分规则