I'm having trouble understanding how the following equivalents work:
x86-64:
/*long loop(long x, int n)*/
/*x in %rdi, n in %esi*/
1.loop:
2 movl %esi, %ecx
3 movl $1, %edx
4 movl $0, %eax
5 jmp .L2
6.L3:
7 movq %rdi,%r8
8 andq %rdx,%r8
9 orq %r8,%rax
10 salq %cl,%rdx
11.L2
12 testq %rdx,%rdx
13 jne .L3
14 rep; ret
C:
1 long loop(long x, int n)
2 {
3 long result = 0;
4 long mask;
5 for (mask = 1; mask != 0; mask = mask << n) {
6 result |= (x & mask);
7 }
8 return result;
9 }
From what I see,
- n = %esi and is copied into %ecx.
- 1 is copied into mask.
- 0 is copied into result.
I would like to know why 1 is copied to mask when the first variable in the C code is result? Wouldn't result = 1 and mask = 0 since that is the correct order in the C program? Furthermore, when I convert the C code to assembly language, I get:
1.loop:
2 movl %rsi, %rcx
3 movl $1, %eax
4 movl $0, %edx
5 jmp .L2
...
So are the registers %eax and %edx interchangeable?