Reputation: 61
#include <stdio.h>
#include <math.h>
int main(int argc, const char *argv[])
{
long i, max;
long sum = 0;
max = (long)pow(2,32);
for (i = 0; i < max; i++) {
sum += i;
}
printf("%ld\n", sum);
return 0;
}
$gcc -S main.c
The question is: In the .L2
code below, -8(%rbp)
always equals zero, and the %rax
is always greater than zero. So this is a infinite loop? And if I compile with gcc -S -O1 main.c
, it is very clear. I am really troubled!
Just a little part of the assembler code:
main:
pushq %rbp
movq %rsp, %rbp
subq $48, %rsp
movl %edi, -36(%rbp)
movq %rsi, -48(%rbp)
movq $0, -16(%rbp)
movl $0, -8(%rbp)
movl $2, -4(%rbp)
movq $0, -24(%rbp)
jmp .L2
.L3:
movq -24(%rbp), %rax
addq %rax, -16(%rbp)
addq $1, -24(%rbp)
.L2:
movq -24(%rbp), %rax
cmpq -8(%rbp), %rax
jl .L3
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
Upvotes: 0
Views: 1051
Reputation: 61396
The real loop counter (i
) is at -24(%rbp)
. On the third line, it's increased. On the 4th line, it's loaded into rax
. So rax
is not a constant zero, it runs through values along with i
.
-8(%rbp)
, one assumes, is where max
is. So the value of i
is compared to that, and this is your loop exit condition. -8(%rbp)
should not be zero. If it is, I smell rogue 32-bit arithmetic.
EDIT: I think I know what's the matter. Constants 2 and 32 are int
, not long
, therefore assumed to be 32-bit. Size of int
is platform dependent; even GCC's convention might vary. pow(int, int)
is implemented as as intrinsic. 2^32 is 0 when arguments are 32-bit.
Replace
max = (long)pow(2,32);
with
max = pow(2l, 32l);
Or better with with a constant:
max = 0x100000000l;
Like I and others suspected, there was a piece of 32-bitness in the mix.
Upvotes: 2
Reputation: 44278
No it is not infinite loop. First of all %rax is not always greater than 0, in that line it gets value from -24(%rbp) which is obviously variable i
. When it enters the loop it sets -24(%rbp) to zero and then jumps to .L2 It happens in part that you did not show. If -8(%rbp) which is value of variable of max
is equal to zero (in case of overflow) jl
will not jump to .L3 and loop will terminate after first check.
I do not quite understand why you need to read assembly for that, that's pretty obvious from C++ source code.
Upvotes: 1