Reputation: 1899
I have the following ARM64 assembly code:
.text
.arch armv8-a
.type testARM64, STT_FUNC
.global testARM64
testARM64:
arg1 .req x0
arg2 .req x1
arg3 .req x2
arg4 .req x3
arg5 .req x4
arg6 .req x5
tmp .req x9
mov tmp, #0
mov x0, #1
bl debugAssembly
mov tmp, #2
ret
.unreq arg1
.unreq arg2
.unreq arg3
.unreq arg4
.unreq arg5
.unreq arg6
.unreq tmp
I call it from:
#include <stdlib.h>
void testARM64(int arg1, int arg2, int arg3, int arg4, int arg5, int arg6);
void debugAssembly(int a) {
fprintf(stderr, "Debug 0x%d\n", a);
}
int main(int argc, char **argv) {
testARM64(0, 0, 0, 0, 0, 0);
return 0;
}
How can I protect the WHOLE stack when branching to debugAssembly? I mean what would be the equivalent of the push/pop ARM instructions that can work WHATEVER the number of arguments and WHATEVER I do inside my assembly with ANY temp registers? (I don't need to protect/save the lanes).
Upvotes: 1
Views: 774
Reputation: 15425
You need to save the fp reg and link register -- often done with something like stp x29, x30, [sp, #0x10]! assuming your platform uses x29 for the fp -- before you call another function and restore the values before exiting the function. Otherwise when you bl your other function, the link register (which holds the caller's return address) will be overwritten. Your ABI probably requires 16-byte alignment of the stack pointer so you'll want to save two registers to the stack even if your platform doesn't use a frame pointer.
I'd recommend disassembling some simple functions that your compiler has generated and use its instructions as a model for your own hand-written routines.
Upvotes: 0