当在C代码中的循环内使用continue语句时,GCC在循环块结束之前创建一个带有nop指令的新标签并跳转到它,而不是跳转到循环块本身的末尾。例如,以下C代码
for (i=0; i<10; i++) {
puts("blah\n");
if (i < 10) continue;
puts("This shouldn't be printed.\n");
}
生成以下ASM等效项(使用gcc -S):
movl $0, 28(%esp)
jmp L2
L5:
movl $LC0, (%esp)
call _puts
cmpl $9, 28(%esp)
jle L7
L3:
movl $LC1, (%esp)
call _puts
jmp L4
L7:
nop
L4:
incl 28(%esp)
L2:
cmpl $9, 28(%esp)
jle L5
(插入if(i&lt; 10)部分,以便编译器不通过删除continue语句后面的任何内容来“优化”该部分)
我的问题是,为什么不直接跳到L4呢? IMO我们也可以跳到L4,我错过了什么?
答案 0 :(得分:4)
您所描述的是优化。当然,如果你告诉gcc进行优化(-O1
就足够了),它就会完全按照你的描述进行。
答案 1 :(得分:1)
我的猜测是,它是某种跳过代码修正序列的占位符。也许nop
有时被替换为将寄存器存储到堆栈或其他类似的指令。
但为了获得更多证据,有助于找到nop
替换为其他内容的示例。