2007年5月8日星期二

微软引起的while不归路

如果你是windows mobile的驱动程序开发人员,又恰好写了类似的这样一句话。
while(dev->devState!=5);
说明一下,dev是个结构体指针。你希望等待它的成员变量变成5,继续执行。同时

有可能你在中断服务程序中改变这个成员变量的值。
哈哈!我幸运的告诉你你已经进入了“死循环”,永远跳不出去啦。

这是个编译器优化产生的问题,看看编译器产生的汇编片段。
|$L39064|
cmp r3, #5
bne |$L39064|
它将dev->devState优化为了一个寄存器r3,这样的比较是跳不出循环的。

那么要解决这个问题就是将dev这个指针声明为volatile,之后,看编译器产生的汇编片段,变成了
|$L39064|
ldr r3, [r6, #4]
cmp r3, #5
bne |$L39064|
这才是我们想要的结果。汗!!

我在WM533做的实验,确实有这个问题。我觉得这个优化,微软做的太离谱了。不知道算不算编译器bug

2 条评论:

Non-human 说...

不算, C/C++ 語言的定義 就是如此, 如果是外在會改變該變數值的 需要加上 volatile, 編譯器才能知道最佳化時要避免預設該變數的行為,
另外你的這個Blog 內容很有料, 有很多看法是讀過 Private code才會知道的內容!! 雖然好久沒碰過WM了

cpuwolf 说...

谢谢