0

I'm doing an assembly x86 program that resolves the determinant of a 2x2 matrix. Well, i've done the driver in C and then I made a function that will be processed in the assembly x86 code. That's the function in C: int det(int,int,int,int) atribute((_cdecl)); My question is: how do I take these four ints (that i passed like as parameters in that function) in x86? how can I operate with them in the x86 code? I think that it could be with the stack, but I don't know how.

  • Oh sorry, I may have misunderstood your question. It seems you want to call assembly from C perhaps? Can you please clarify? If that is the case can you also show your assembly code? Are you trying to write inline assembly or standalone assembly - the answer will depend on which it is. – kaylum Feb 05 '21 at 22:03
  • yes. that's it. here is the code. the C code: – Tiki Quaglia Feb 06 '21 at 13:12
  • #include int det(int,int,int,int) __atribute__((_cdecl)); void main(void){ int v[4],i; for(i=0;i<4;++i){ printf("Ingrese valor para '%c':\t",97+i); scanf("%d",&v[i]); } printf("El determinante de la matriz ingresada es %d.\n",det(v[0],v[1],v[2],v[3])); } – Tiki Quaglia Feb 06 '21 at 13:13
  • i'm from Argentina so the printf' text is in spanish – Tiki Quaglia Feb 06 '21 at 13:13
  • The duplicate is wrong. This is how to call Assembly functions from C. – DarkAtom Feb 06 '21 at 14:52

1 Answers1

0

What you are basically asking is: where are the parameters located, right?

cdecl passes all arguments on the stack, in reverse order. Look up the specs of that calling convention.

So for your function:

int det(int p1, int p2, int p3, int p4);

Your stack will look like this at the beginning of your function:

p4
p3
p2
p1
return address

esp always points to the return address. esp+4 points to p1, esp+8 points to p2 etc..

Please note:

As you are using the cdecl calling convention, you must preserve all registers, except eax, ecx and edx. When you execute ret, all other registers must be the same as they were when you entered the function.

The return value goes in eax.

Here's an example, using NASM syntax. Note that I didn't include a stack frame for the function, because it is a short leaf function, so it is a waste:

; UNTESTED
; int det(int a11, int a12, int a21, int a22)
_det:
    mov ecx, [esp + 4]
    mov edx, [esp + 12]
    imul ecx, edx
    mov eax, [esp + 8]
    mov edx, [esp + 16]
    imul eax, edx
    sub ecx, eax
    mov eax, ecx
    ret
DarkAtom
  • 2,589
  • 1
  • 11
  • 27
  • thanks you! i can understand it. So, using the example that you've done with the stack, the last element of the stack will be p4? – Tiki Quaglia Feb 06 '21 at 13:23
  • @TikiQuaglia The stack doesn't have a "last element". It has a top. The fifth element from the top is `p4`. Beyond `p4` lies the caller's stack frame, which has local variables, it's own return address etc. – DarkAtom Feb 06 '21 at 13:26
  • ohh ok. so if i continue passing things to the stack, they will be after p4 or before the return adress? – Tiki Quaglia Feb 06 '21 at 13:34
  • @TikiQuaglia if you push another element on the stack, it will be placed on top of the return address. But if you do, then the return address will be [esp+4] instead of [esp]. Note that before you return, you must pop all elements that you pushed, so that you leave the return address on top. You don't need to pop the parameters. – DarkAtom Feb 06 '21 at 13:38
  • If you want to use the stack inside the function, it is best to create a stack frame. – DarkAtom Feb 06 '21 at 13:40
  • ok. thanks you!. i didn't remember that the stack grows to downside. when i realize it everything make sense. – Tiki Quaglia Feb 06 '21 at 13:50