First of all, you mixed the values ββin your code. %esi starts at b and %edi starts at a .
You can deduce from the line testl %edx, %edx that %edx used as a condition variable for a loop starting with .L7 (if %edx is other than 0, then control is passed to .L9 and then returns to .L7 ). We will refer to %edx as remainder in our reverse engineering code.
Let's begin to reconstruct the main loop:
movl %edi, %edx
Since %edi stores a , this is equivalent to initializing the remainder value with a : int remainder = a; .
movl %edi, %eax
Save int temp = a;
movl %esi, %edi
Run int a = b; (remember that %edi is a and %esi is b ).
sarl $31, %edx
This arithmetic shift instruction shifts our remainder variable 31 bits to the right, keeping the sign of the number. By moving 31 bits, you set remainder to 0 if it is positive (or zero) and -1 if it is negative. So this is equivalent to remainder = (remainder < 0) ? -1 : 0 remainder = (remainder < 0) ? -1 : 0 .
idivl %esi
Divide %edx:%eax by %esi or in our case divide remainder * temp by b (variable). The rest will be saved in %edx or in our remainder code. When combining this with the previous statement: if remainder < 0 then remainder = -1 * temp % b and otherwise remainder = temp % b .
testl %edx, %edx jne .L9
Make sure that if remainder is 0 - if not, go to .L9 . The code there just sets b = remainder; before returning to .L7 . To implement this in C, we will save the variable count , which will store the number of times the loop repeats. We do b = remainder at the beginning of the loop, but only after the first iteration, which means count != 0 .
Now we are ready to build our complete C cycle:
int count = 0; do { if (count != 0) b = remainder; remainder = a; temp = a; a = b; if (remainder < 0){ remainder = -1 * temp % b; } else { remainder = temp % b; } count++; } while (remainder != 0)
And after completing the cycle,
movl %esi, %eax ret
It will return the GCD that the program calculated (in our code it will be stored in variable b ).