GCC生成的程序集相当于C中的continue语句

时间:2010-03-01 10:20:48

标签: c gcc assembly

当在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,我错过了什么?

2 个答案:

答案 0 :(得分:4)

您所描述的是优化。当然,如果你告诉gcc进行优化(-O1就足够了),它就会完全按照你的描述进行。

答案 1 :(得分:1)

我的猜测是,它是某种跳过代码修正序列的占位符。也许nop有时被替换为将寄存器存储到堆栈或其他类似的指令。

但为了获得更多证据,有助于找到nop替换为其他内容的示例。