You need to try assembling it and see what error messages gas will give you.
Line 32 looks suspect. (You made me pull out my manual.) There is no IMUL opcode that takes three r/m32 operands. What x86 instruction reference are you using? (I'll take a look over it to give better answers.)
Lastly, the multiplication opcodes have implicit operand modes which are typically very useful.
One last thing: on the Intel processors each register has specific characteristics that make it particularly useful for certain tasks (or the only one usable for a given task):
EAX -- accumulator, return values, temporaries, etc.
EBX -- base (from which other registers are offset. Often used to index the stack)
ECX -- counter (the only register you can use for loops and string operations)
EDX -- general data
ESI -- source index (paired with EDS for string operations)
EDI -- destination index (paired with EES or EDS for string operations, depending on instruction used)
ESP -- stack pointer (you already know that)
EBP -- base pointer (used for subroutine stack frames) |
hmm... what else, segment registers ECS, EDS, EES, EFS, EGS... that's all I can think of off the top of my head right now.
The way I would have translated the routine is (well, I would have made it a little more efficient, but this will do):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
.text
.globl func
func:
; // stack frame: you did this right
pushl %%ebp
movl %%esp, %ebp
; // eax := temp = n1 * n2
movl 8(%%ebp), %%eax ; // temp = n1
imull 12(%%ebp), %%eax ; // temp *= n2
; // temp -= (n1 + n2)
subl 8(%%ebp), %%eax ; // temp -= n1
subl 12(%%ebp), %%eax ; // temp -= n2
; // return temp
popl %%ebp
ret
|
This function assumes
__cdecl calling convention. So if you assemble it into an object file and link it into your C application, you would use it like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
#include <stdio.h>
extern __cdecl int func( int n1, int n2 );
int main()
{
int a, b;
printf( "%s", "Please enter two integer numbers> " );
scanf( "%d %d", &a, &b );
printf( "%s %d\n", "The result of 'func( a, b )' is", func( a, b ) );
return 0;
}
|
Notice how I kept register usage down, and I used EAX for the things it does best.
I can't stand AT&T syntax. I believe you can get GAS to take Intel syntax if you like.
I have pretty much typed this in off the top of my head. Mistakes may have occurred.
Hope this helps.