while汇编语言循环

时间:2011-09-21 07:40:19

标签: c++ assembly

C ++中有这样的代码:

#include <iostream>

int main(){
  int a = 4;
  while(a--){
    std::cout << (a + 1) << '\n';
  }
  return 0;
}

和g ++生成的汇编代码中主函数的相应代码:

.globl main
    .type   main, @function
main:
.LFB957:
    .cfi_startproc
    .cfi_personality 0x0,__gxx_personality_v0
    pushl   %ebp
    .cfi_def_cfa_offset 8
    movl    %esp, %ebp
    .cfi_offset 5, -8
    .cfi_def_cfa_register 5
    andl    $-16, %esp
    subl    $32, %esp
    movl    $4, 28(%esp)    # int a = 4;
    jmp .L2
.L3:
    movl    28(%esp), %eax     # std::cout << (a + 1) << '\n';
    addl    $1, %eax
    movl    %eax, 4(%esp)
    movl    $_ZSt4cout, (%esp)
    call    _ZNSolsEi
    movl    $10, 4(%esp)
    movl    %eax, (%esp)
    call    _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_c
.L2:
    cmpl    $0, 28(%esp)
    setne   %al
    subl    $1, 28(%esp)    # a = a - 1
    testb   %al, %al
    jne .L3
    movl    $0, %eax
    leave
    ret
    .cfi_endproc
.LFE957:
    .size   main, .-main

以下片段中使用的指令setne和testb是什么?

 .L2:
        cmpl    $0, 28(%esp)
        setne   %al
        subl    $1, 28(%esp)    # a = a - 1
        testb   %al, %al
        jne .L3

在循环中检查是否a不是零并且跳转是不是这样?

3 个答案:

答案 0 :(得分:5)

while条件正式相当于:

while ( a -- != 0 )

(省略比较是合法的混淆。)

编译器正在生成代码以将a0进行比较,保存 导致注册al,然后递减a,然后测试保存的 结果。

答案 1 :(得分:1)

因为a--表示

tmpval=a;
a=a-1;
return tmpval;

因此编译器需要保存a的先前值。 在此程序中,while的正文部分将在a = 0后执行(a--之后,因此它将打印1)。

答案 2 :(得分:0)

自从我做汇编程序以来已经有很长一段时间了,但我认为这是保持管道繁忙/优化寄存器使用的一些优化。