社区导航

 
快捷导航
  • 首页
  • 论坛
  • 查看新帖
  • 最新回复
  • 社区活动
  • 联系管理员
  • 消灭零回复
  • E金币兑换
  • 干货
搜索
查看: 1468|回复: 5

[讨论] 反汇编arm9代码,为什么调用两次bic,gcc犯傻吗???

[复制链接]

239

TA的帖子

2

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

发表于 2014-8-14 19:10:33 | 显示全部楼层 |阅读模式
如下三段汇编代码
        a &= ~(1 << 7);//a &= ~0x80
e3c:        e51b300c         ldr        r3, [fp, #-12]
e40:        e3c33080         bic        r3, r3, #128        ; 0x80
e44:        e50b300c         str        r3, [fp, #-12]

        a &= ~((1 << 2)|(1 << 3)| (1 << 4)| (1 << 8)| (1 << 16));//a &= ~0x10284 e1c:        e51b300c         ldr        r3, [fp, #-12]
e20:        e3c33801         bic        r3, r3, #65536        ; 0x10000
e24:        e3c33f47         bic        r3, r3, #284        ; 0x11c
e28:        e50b300c         str        r3, [fp, #-12]

        tmpreg &= ~((7 << 0) | (7 << 4) | (7 << 8) | (8 << 16));//tmpreg &= ~0x80777 5b8:        e51b3008         ldr        r3, [fp, #-8]
5bc:        e3c33702         bic        r3, r3, #524288        ; 0x80000
5c0:        e3c33e77         bic        r3, r3, #1904        ; 0x770
5c4:        e3c33007         bic        r3, r3, #7        ; 0x7

5c8:        e50b3008         str        r3, [fp, #-8]


我发现反汇编后的bic指令,凡是数大于0xFFFF后就被分成多分,如果R3是16位寄存器,那么理论上0xFFFFFFFF这样的数执行两次bic指令也能运行完。
但是为什么第3个例子里好好的0x80777被分成0x80000、0x770、0x7呢?

虽然这样把代码分成了多份?是不是考虑到“三级流水线”而设计的呢?因为我不相信编译器会犯傻,或许这还是个妙招,保证流水线不被打乱

虽然bic被分成2、3行代码,但与执行1行代码是等同效率的?
此帖出自ARM技术论坛


回复

使用道具 举报

239

TA的帖子

2

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

 楼主| 发表于 2014-8-14 19:19:16 | 显示全部楼层
a &= ~((1 << 2)|(1 << 3)| (1 << 4)| (1 << 8)| (1 << 16));//a &= ~0x10284 e1c:        e51b300c         ldr        r3, [fp, #-12]
这行写错了,改成
a &= ~((1 << 2)|(1 << 3)| (1 << 4)| (1 << 8)| (1 << 16));//a &= ~0x1011c e1c:        e51b300c         ldr        r3, [fp, #-12]


回复

使用道具 举报

5125

TA的帖子

73

TA的资源

版主

Rank: 6Rank: 6

爱原创

发表于 2014-8-14 20:16:45 | 显示全部楼层
据我猜测,可能是用一条指令指令完不成吧,所以会拆成两条,要不你试试用汇编写写,用一条指令完成,可能你也做不到。所以指令会用一个小的常量去左右移来完成。
EEWORLD开发板置换群:309018200,——电工们免费装β的天堂,商家勿入!加群暗号:喵


回复

使用道具 举报

665

TA的帖子

1

TA的资源

纯净的硅(中级)

Rank: 5Rank: 5

发表于 2014-8-15 08:55:28 | 显示全部楼层
指令里带有的立即数是有范围的,如果你要的那个数比较复杂,那么就不能表示在一条指令里了。当然如果你想硬用一个数来编写汇编指令是没问题的,不过这个时候指令里就不是立即数了,而是一个间接数,所以需要CPU再到内存中把这个数取出来放在寄存器里,这样一系列操作,可能就得不偿失了,不如多用两条指令,省的CPU还得跑一遍内存。


回复

使用道具 举报

239

TA的帖子

2

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

 楼主| 发表于 2014-8-15 11:34:11 | 显示全部楼层
大概明白了


回复

使用道具 举报

239

TA的帖子

2

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

 楼主| 发表于 2014-8-16 15:20:29 | 显示全部楼层
韦东山的视频
毕业班第1课第1.1节_自己写bootloader之编写第1阶段
http://www.tudou.com/programs/view/3qmAuCjzTUo/
毕业班第1课第2节_自己写bootloader之编译测试
http://www.tudou.com/programs/view/Yy67rZVidPo/
13:00分
两个视频有讲述为什么立即数被拆分操作,寄存器位宽不足


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2017-11-20 11:56 , Processed in 1.552635 second(s), 15 queries , Redis On.

快速回复 返回顶部 返回列表