首先叙述下我的问题,编译器是 64bit 编译器,主要代码如下:
#define _BIT(n) (((unsigned )(1)) << (n))
void __write_icr(int idx, unsigned short value, int irq)
{
printk("icr_dump %d %d %d %p %p %p\n", irq, idx, value, &idx, &value, &irq);
}
int main()
{
for(int i = 1; i < 63; i++){
__write_icr(i>>4, _BIT( (i & 0x1F) ), i);
}
return 0;
}
我省略了其他无关代码, 主要就是 main 函数里调用 __write_icr 函数。 注意 __write_icr 的第二个参数是 unsigned short 类型.
我提取了编译的中间文件,main 函数里的循环对应汇编如下:
.L31:
add x19, x19, 1
cmp x19, 2
bne .L33
mov w19, 1
.loc 1 371 0
mov w20, w19
.L34:
mov w2, w19
lsl w1, w20, w19
asr w0, w19, 4
bl __write_icr
.LVL89:
add w19, w19, 1
cmp w19, 63
bne .L34
mov w0, 64
不知道为什么,(i & 0x1F) 这个操作被编译器忽略掉了, 导致后续传到 __write_icr 的数据不对。
但如果我吧 __write_icr 第二个类型修改为 unsigned int value, 编译出来就感觉是正确的。
.L31:
add x19, x19, 1
cmp x19, 2
bne .L33
mov w19, 1
.loc 1 371 0
mov w20, w19
.L34:
and w1, w19, 15
mov w2, w19
lsl w1, w20, w1
asr w0, w19, 4
bl __write_icr
.LVL89:
add w19, w19, 1
cmp w19, 63
bne .L34
mov w0, 64
其中会有这句 (and w1, w19, 15), 对应着 (i & 0x1F)。 试了很多次,原因就是使用 short 类型时这句话时这个与操作被编译器优化掉了,这个是正常的吗,还是我自己理解太浅了。。。
请各位大神帮忙指点下
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.