汇编语言中的While循环

while loop in assembly language

本文关键字:循环 While 汇编语言      更新时间:2023-10-16

c++中有这样的代码:

#include <iostream>
int main(){
  int a = 4;
  while(a--){
    std::cout << (a + 1) << 'n';
  }
  return 0;
}
c++汇编代码中

和main函数对应的代码:

.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

下列片段中的set和testb指令是用来干什么的?

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

在while循环中检查a是否不为零,然后跳转,这样不行吗?

while条件在形式上相当于:

while ( a -- != 0 )

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

编译器正在生成比较a0的代码,保存结果寄存器al,然后递减a,然后测试保存的结果。

因为a--意味着

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

所以编译器需要保存a的前一个值。在这个程序中,while的主体部分将在a = 0(在a--之后,所以它将打印1)时执行。

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