I would like to call an assembly function from C. It is part of a basic example for calling conventions.
The function is a basic:
int mult(int A, int B){
return A*B
}
According to the Procedure Call Standard for the
ARMĀ® Architecture the parameters A
and B
should be in registers r0
and r1
respectively for the function call. The return value should be in r0
.
Essentially then I would expect the function to be:
EXPORT mult
mult MULT r0, r0, r1
BX lr
With GCC 7.2.1 (none) -O1 -mcpu=cortex-m4 -mabi=aapcs, I get the following: (using Compiler Explorer)
mult:
mul r0, r1, r0
bx lr
Which is what I expected. However. If I disable optimizations (-O0) I get the following nonsense:
mult:
push {r7}
sub sp, sp, #12
add r7, sp, #0
str r0, [r7, #4]
str r1, [r7]
ldr r3, [r7, #4]
ldr r2, [r7]
mul r3, r2, r3
mov r0, r3
adds r7, r7, #12
mov sp, r7
pop {r7}
bx lr
Which means GCC is using r7
as a frame pointer I think and passing all of the parameters and return values via the stack. Which is not according to the AAPCS.
Is this a bug with Compiler Explorer, GCC or have I missed something in the AAPCS? Why would -O0 have a fundamentally different calling convention than specified in the AAPCS document?
str
). Inside the function, it copies them to the stack before reading them back, but that has no effect on the calling convention. - Marc Glisse