I have the following function in C:
uint myFunction (uint arrayLen,
uint* array
)
{
uint i;
uint j;
uint sum = 0;
for (i = 0; i < arrayLen/2; i++)
for (j = 0; j < arrayLen; j++)
if (array[i*2] == array[j])
sum += mySumFunction(arrayLen,array,6);
mySortFunction(arrayLen,array);
for (i = 0; i < arrayLen/2; i++)
for (j = 0; j < arrayLen; j++)
if (array[i*2] == array[j])
sum -= mySumFunction(arrayLen,array,7);
return(sum);
}
And here's the output for the disassemble command on the function
Dump of assembler code for function myFunction:
0x080486a8 <myFunction+0>: push %ebp
0x080486a9 <myFunction+1>: mov %esp,%ebp
0x080486ab <myFunction+3>: sub $0x1c,%esp
0x080486ae <myFunction+6>: call 0x8048418 <mcount@plt>
0x080486b3 <myFunction+11>: movl $0x0,-0x4(%ebp)
0x080486ba <myFunction+18>: movl $0x0,-0xc(%ebp)
0x080486c1 <myFunction+25>: jmp 0x8048713 <myFunction+107>
0x080486c3 <myFunction+27>: movl $0x0,-0x8(%ebp)
0x080486ca <myFunction+34>: jmp 0x8048707 <myFunction+95>
0x080486cc <myFunction+36>: mov -0xc(%ebp),%eax
0x080486cf <myFunction+39>: shl $0x3,%eax
0x080486d2 <myFunction+42>: add 0xc(%ebp),%eax
0x080486d5 <myFunction+45>: mov (%eax),%edx
0x080486d7 <myFunction+47>: mov -0x8(%ebp),%eax
0x080486da <myFunction+50>: shl $0x2,%eax
0x080486dd <myFunction+53>: add 0xc(%ebp),%eax
0x080486e0 <myFunction+56>: mov (%eax),%eax
0x080486e2 <myFunction+58>: cmp %eax,%edx
0x080486e4 <myFunction+60>: jne 0x8048703 <myFunction+91>
0x080486e6 <myFunction+62>: movl $0x6,0x8(%esp)
0x080486ee <myFunction+70>: mov 0xc(%ebp),%eax
0x080486f1 <myFunction+73>: mov %eax,0x4(%esp)
0x080486f5 <myFunction+77>: mov 0x8(%ebp),%eax
0x080486f8 <myFunction+80>: mov %eax,(%esp)
0x080486fb <myFunction+83>: call 0x8048668 <mySumFunction>
0x08048700 <myFunction+88>: add %eax,-0x4(%ebp)
0x08048703 <myFunction+91>: addl $0x1,-0x8(%ebp)
0x08048707 <myFunction+95>: mov -0x8(%ebp),%eax
0x0804870a <myFunction+98>: cmp 0x8(%ebp),%eax
0x0804870d <myFunction+101>: jb 0x80486cc <myFunction+36>
0x0804870f <myFunction+103>: addl $0x1,-0xc(%ebp)
0x08048713 <myFunction+107>: mov 0x8(%ebp),%eax
0x08048716 <myFunction+110>: shr %eax
0x08048718 <myFunction+112>: cmp -0xc(%ebp),%eax
0x0804871b <myFunction+115>: ja 0x80486c3 <myFunction+27>
0x0804871d <myFunction+117>: mov 0xc(%ebp),%eax
0x08048720 <myFunction+120>: mov %eax,0x4(%esp)
0x08048724 <myFunction+124>: mov 0x8(%ebp),%eax
0x08048727 <myFunction+127>: mov %eax,(%esp)
0x0804872a <myFunction+130>: call 0x80485cc <mySortFunction>
0x0804872f <myFunction+135>: movl $0x0,-0xc(%ebp)
0x08048736 <myFunction+142>: jmp 0x8048788 <myFunction+224>
0x08048738 <myFunction+144>: movl $0x0,-0x8(%ebp)
0x0804873f <myFunction+151>: jmp 0x804877c <myFunction+212>
0x08048741 <myFunction+153>: mov -0xc(%ebp),%eax
0x08048744 <myFunction+156>: shl $0x3,%eax
0x08048747 <myFunction+159>: add 0xc(%ebp),%eax
0x0804874a <myFunction+162>: mov (%eax),%edx
0x0804874c <myFunction+164>: mov -0x8(%ebp),%eax
0x0804874f <myFunction+167>: shl $0x2,%eax
0x08048752 <myFunction+170>: add 0xc(%ebp),%eax
0x08048755 <myFunction+173>: mov (%eax),%eax
0x08048757 <myFunction+175>: cmp %eax,%edx
0x08048759 <myFunction+177>: jne 0x8048778 <myFunction+208>
0x0804875b <myFunction+179>: movl $0x7,0x8(%esp)
0x08048763 <myFunction+187>: mov 0xc(%ebp),%eax
0x08048766 <myFunction+190>: mov %eax,0x4(%esp)
0x0804876a <myFunction+194>: mov 0x8(%ebp),%eax
0x0804876d <myFunction+197>: mov %eax,(%esp)
0x08048770 <myFunction+200>: call 0x8048668 <mySumFunction>
0x08048775 <myFunction+205>: sub %eax,-0x4(%ebp)
0x08048778 <myFunction+208>: addl $0x1,-0x8(%ebp)
0x0804877c <myFunction+212>: mov -0x8(%ebp),%eax
0x0804877f <myFunction+215>: cmp 0x8(%ebp),%eax
0x08048782 <myFunction+218>: jb 0x8048741 <myFunction+153>
0x08048784 <myFunction+220>: addl $0x1,-0xc(%ebp)
0x08048788 <myFunction+224>: mov 0x8(%ebp),%eax
0x0804878b <myFunction+227>: shr %eax
0x0804878d <myFunction+229>: cmp -0xc(%ebp),%eax
0x08048790 <myFunction+232>: ja 0x8048738 <myFunction+144>
0x08048792 <myFunction+234>: mov -0x4(%ebp),%eax
0x08048795 <myFunction+237>: leave
0x08048796 <myFunction+238>: ret
End of assembler dump.
I was wondering if someone could help me read and translate the assembly instructions to the C code above. I was specifically looking for an explanation regarding the division portion seen in the code (arrayLen/2)
. I was under the impression that it would translate into a right shift instruction, but when I didn't see that in the assembly code I wasn't sure what was happening.
Edit: I've added the missing assembly code. It also looks like I found the explanation for the division portion.
It doesn't look like you have the whole function, but here's a breakdown of what's here:
These 3 instructions set up your stack frame:
0x080486a8 <myFunction+0>: push %ebp
0x080486a9 <myFunction+1>: mov %esp,%ebp
0x080486ab <myFunction+3>: sub $0x1c,%esp
I'm not sure what this is for:
0x080486ae <myFunction+6>: call 0x8048418 <mcount@plt>
This is i and sum getting initialized to 0 (the are stored on the stack):
0x080486b3 <myFunction+11>: movl $0x0,-0x4(%ebp)
0x080486ba <myFunction+18>: movl $0x0,-0xc(%ebp)
This is the beginning of the outer for loop. Typically, a loop in assembly starts by jumping to the end. The end in this case is past the end of your assembly listing.
0x080486c1 <myFunction+25>: jmp 0x8048713 <myFunction+107>
This is j getting initialized to 0. It's done here because it has to be reset every time the outer for loop runs.
0x080486c3 <myFunction+27>: movl $0x0,-0x8(%ebp)
This is the beginning of the inner for loop.
0x080486ca <myFunction+34>: jmp 0x8048707 <myFunction+95>
This indexes array by i*2 by doing pointer arithmetic on the address of array. First it puts i into eax, then left shifts it 3 (multiplying it by 8). This is an optimization of the *2 as well as accounting for the size of elements of array (4). Finally it adds this to the address of array, storing the result in eax.
0x080486cc <myFunction+36>: mov -0xc(%ebp),%eax
0x080486cf <myFunction+39>: shl $0x3,%eax
0x080486d2 <myFunction+42>: add 0xc(%ebp),%eax
This takes the value pointed to by address calculated above and stores it in edx. In this dialect of assembly x(y) means *(y+x)
0x080486d5 <myFunction+45>: mov (%eax),%edx
This calculates array[j] in a similar fashion, storing the result in eax this time:
0x080486d7 <myFunction+47>: mov -0x8(%ebp),%eax
0x080486da <myFunction+50>: shl $0x2,%eax
0x080486dd <myFunction+53>: add 0xc(%ebp),%eax
0x080486e0 <myFunction+56>: mov (%eax),%eax
This checks the two calculations above to see if they are equal:
0x080486e2 <myFunction+58>: cmp %eax,%edx
If the check doesn't pass (if they are not equal), skip the inside of the if. (This jumps past the end of your listing) jne means "jump if not equal"
0x080486e4 <myFunction+60>: jne 0x8048703 <myFunction+91>
These instructions load the arguments of mySumFunction into the proper places:
0x080486e6 <myFunction+62>: movl $0x6,0x8(%esp)
0x080486ee <myFunction+70>: mov 0xc(%ebp),%eax
0x080486f1 <myFunction+73>: mov %eax,0x4(%esp)
If the listing is cut off here, but hopefully this gives you a good general idea.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With