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不是零并且跳转是不是这样?
答案 0 :(得分:5)
while条件正式相当于:
while ( a -- != 0 )
(省略比较是合法的混淆。)
编译器正在生成代码以将a
与0
进行比较,保存
导致注册al
,然后递减a
,然后测试保存的
结果。
答案 1 :(得分:1)
因为a--
表示
tmpval=a;
a=a-1;
return tmpval;
因此编译器需要保存a
的先前值。
在此程序中,while的正文部分将在a = 0
后执行(a--
之后,因此它将打印1
)。
答案 2 :(得分:0)
自从我做汇编程序以来已经有很长一段时间了,但我认为这是保持管道繁忙/优化寄存器使用的一些优化。