Reputation: 508
Suppose I am given as input to a function foo
some pointer *pL
that points to a pointer to a struct that has a pointer field next in it. I know this is weird, but all I want to implement in assembly is the line of code with the ** around it:
typedef struct CELL *LIST;
struct CELL {
int element;
LIST next;
};
void foo(LIST *pL){
**(*pL)->next = NULL;**
}
How do I implement this in ARM assembly? The issue comes from having nested startements when I want to store such as:
.irrelevant header junk
foo:
MOV R1, #0
STR R1, [[R0,#0],#4] @This is gibberish, but [R0,#0] is to dereference and the #4 is to offeset that.
Upvotes: 0
Views: 4877
Reputation: 28941
The sequence would be similar to:
... ; r0 = LIST *pL = CELL **ppC (ptr2ptr2cell)
ldr r0,[r0] ; r0 = CELL *pC (ptr2cell)
mov r1,#0 ; r1 = NULL
str r1,[r0,#4] ; (*pL)->next = pC->next = (*pC).next = NULL
Upvotes: 3
Reputation: 22469
The correct sequence would be (assuming ARM ABI and LIST *pL
is in R0),
.global foo
foo:
ldr r0, [r0] # get *pL to R0
mov r1, #0 # set R1 to zero.
str r1, [r0, #4] # set (*pL)->List = NULL;
bx lr # return
You can swap the first two assembler statements, but it is generally better to interleave ALU with load/store for performance. With the ARM ABI, you can use R0-R3 without saving. foo()
above should be callable from 'C' with most ARM compilers.
The 'C' might be simplified to,
void foo(struct CELL **pL)
{
(*pL)->next = NULL;
}
if I understand correctly.
Upvotes: 1