Reputation: 4988
A course of ARM assembly recently started at my university, and or assignment is to create an NxM * MxP matrix multiplication programm, that is called from C code.
Now I have a fairly limited knowledge in assambler, but i'm more than willing to learn. What I would like to know is this:
I'm thinking, that i can figure the rest of this out by myself, but these 2 points are what I find difficult.
I am using ARM assembly on qemu, on Ubuntu for this code, it's not going on any particular device.
Upvotes: 0
Views: 5600
Reputation: 4988
Even though Guillaumes answer helped me A LOT, I just thought to answer my own question with a bit of code.
What I ended up doing was creating an a 1D array, and passing it to asm along with the dimensions.
int *p;
scanf("%d", &h1);
scanf("%d", &w1);
int* A =(int *) malloc (sizeof(int) * ( w1 * h1 ));
p=A;
int i;
int j;
for(i=0;i<(w1*h1);i++)
{
scanf("%d", p++);
}
That being said, I allocated another array the same (malloc
) way, and passed it along aswell. I then just stored the int value I needed in the appropriate address in the assembly code, and since the addresses of the array elements don't change, I just used the same array to output the result.
Upvotes: 0
Reputation: 311
C arrays are merely just pointers, so when you pass a C array as an argument to an assemply function, you will get a pointer to an area of memory that is the content of the array.
For retrieving the argument, it depends on what calling convention you use. The ARM EABI stipulates that:
The first four registers r0-r3 (a1-a4) are used to pass argument values into a subroutine and to return a result value from a function. They may also be used to hold intermediate values within a routine (but, in general, only between subroutine calls).
For simple functions, them, you should find the pointer to your array in r0 to r4 depending on your function signature. Otherwise, you will find it on the stack. A good technique to find out exactly what the ABI is would be to disassemble the object file of the C code that calls your assembly function and check what it does prior to calling your Assembly function.
For instance, on Linux, you can compile the following C code in a file called testasm.c
:
extern int myasmfunc(int *);
static int array[] = { 0, 1, 2 };
int mycfunc()
{
return myasmfunc(array);
}
Then compile it with:
arm-linux-gnueabi-gcc -c testasm.c
And finally get a disassembly with:
arm-linux-gnueabi-objdump -S testasm.o
The result is:
testasm.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <mycfunc>:
0: e92d4800 push {fp, lr}
4: e28db004 add fp, sp, #4
8: e59f000c ldr r0, [pc, #12] ; 1c <mycfunc+0x1c>
c: ebfffffe bl 0 <myasmfunc>
10: e1a03000 mov r3, r0
14: e1a00003 mov r0, r3
18: e8bd8800 pop {fp, pc}
1c: 00000000 andeq r0, r0, r0
You can see that the single-parametered function myasmfunc
is called by putting the parameter into register r0
. The meaning of ldr r0, [pc, #12]
is "load into r0
the content of the memory address that is at pc+12
". That is where the pointer to the array is stored.
Upvotes: 2