c - Leal instruction in for loop -
i'm reading book computer systems: programmer's perspective (2nd edition) , practice problem 3.23 little confused me:
a function fun_b has following overall structure:
int fun_b(unsigned x) { int val = 0; int i; ( ____;_____;_____) { } return val; }
the gcc c compiler generates following assembly code:
x @ %ebp+8 1 movl 8(%ebp), %ebx 2 movl $0, %eax 3 movl $0, %ecx .l13: 5 leal (%eax,%eax), %edx 6 movl %ebx, %eax 7 andl $1, %eax 8 orl %edx, %eax 9 shrl %ebx shift right 1 10 addl $1, %ecx 11 cmpl $32, %ecx 12 jne .l13
reverse engineer operation of code , following:
a. use assembly-code version fill in missing parts of c code.
my solution.
int fun_b(unsigned x) { int val = 0; int i; ( = 0 ;i < 32;i++) { val += val; //because leal (%eax,%eax), edx --> %edx = %eax + %eax val = val | x & 0x1; x >>= 1; } return val; }
book's solution.
int fun_b(unsigned x) { int val = 0; int i; (i = 0; < 32; i++) { val = (val << 1) | (x & 0x1); x >>= 1; } return val; }
please, explain me why leal function has non typical behavior in function. , dont understand how assembly code yielding statement val = (val << 1) | (x & 0x1)
in code:
val += val; val = val | x & 0x1;
here, val += val
equivalent (val*2)
equal val
left shifted 1
.
but think solution correct if assembly code like:
x @ %ebp+8 1 movl 8(%ebp), %ebx 2 movl $0, %eax 3 movl $0, %ecx .l13: 5 addl %eax, %eax 6 movl %ebx, %edx 7 andl $1, %edx 8 orl %edx, %eax 9 shrl %ebx # shift right 1 10 addl $1, %ecx 11 cmpl $32, %ecx 12 jne .l13
because if val + val
separate statement, compiler places in eax register rather in edx (i'm not sure case always). so, code have given, possible solutions are:
val = (val << 1) | (x & 0x1);
or
val = (val + val) | (x & 0x1);
or
val = (val * 2) | (x & 0x1);
Comments
Post a Comment