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.
Asked
Active
Viewed 130 times
0
-
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 Answers
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