这是我正在调试的代码,当我发现这个(我觉得很有趣)。
int function(void) {
static int i, state = 0;
switch (state) {
case 0: goto LABEL0;
case 1: goto LABEL1;
}
LABEL0: /* start of function */
for (i = 0; i < 10; i++) {
state = 1; /* so we will come back to LABEL1 */
return i;
LABEL1:; /* resume control straight after the return */
}
}
所以我观察到的是,这句话 - goto LABEL1;
永远不会将PC直接移动到标签当标签位于循环之后的代码中。到现在为止还挺好。当我将代码更改为此并再次调试时,事情变得非常混乱:
int function(void) {
static int i, state = 0;
switch (state) {
case 0: goto LABEL0;
case 1: goto LABEL1;
}
for(;;){
i++;
LABEL0: /* start of function */
for (i = 0; i < 10; i++) {
state = 1; /* so we will come back to LABEL1 */
return i;
LABEL1:; /* resume control straight after the return */
}
}
}
我故意将LABEL0
嵌套到循环中,以便我可以确认观察到的结果。虽然观察结果并未证实预期结果。这次goto
语句在程序引用的标签之后将程序直接发送到代码(LABEL0:)
,尽管标签嵌套在虚拟for(;;)
循环中。
我真的希望你能得到这个场景。任何人都可以解释这种行为(我找不到一致性)?
答案 0 :(得分:0)
调试器通常不会非常准确地显示PC,因为单个源代码行由多个操作码组成,有时根本没有操作码,因此它无法始终将PC映射到正确的源代码行。 / p>
在第一个示例中的LABEL1
之后放置一个虚拟语句,以查看是否在那里设置了PC。
另一种方法是切换到反汇编视图&#39;或类似的,如果您的调试器支持它。