Falling off the end of a naked
function is not actually an error. Warning in that case was a GCC bug that was fixed somewhere before GCC 5.4. (But code-gen is the same; older GCC versions that warn don't break your code.)
There are only a few minor benefits to writing a naked
function in C + asm:
- Having the compiler emit thumb vs. ARM directives if you have code that can compile for either mode. (Cortex-M0 is thumb-only so no benefit for your case.)
- debug info, dynamic library function size, and other metadata stuff like that.
- get the compiler to do C++ name mangling for you instead of declaring it
extern "C"
, if you were writing C++.
- You can maintain it next to some actual C code it interacts with.
Otherwise you might as well just write a separate asm file. It still can't inline like a non-naked
wrapper function around a GNU C Extended asm statement could.
I'm not an ARM expert, but there's nothing wrong with the way you were using inline asm / naked
function. The body of a naked
is basically the only sane use-case for GNU C "Basic" asm (no constraints).
If you compile this with the right GCC options, GCC should emit the same directives you were using in stand-along asm. (Although not .cantunwind
in case that matters.)
From Godbolt, gcc5.4.1 -O2 -Wall -mcpu=cortex-m0 -mthumb -fverbose-asm
compiles it cleanly (no warnings). This is the asm output, with directives unfiltered, but some manual editing to remove directives and labels I think are just clutter (including debug info):
.syntax unified
.cpu cortex-m0
.fpu softvfp
.text
.global dummy
.code 16
.thumb_func
.type dummy, %function
dummy:
.syntax divided
push {r1-r7, lr}
MOV R0, R3
pop {r1-r7, pc}
.thumb
.syntax unified
.cfi_endproc
.size dummy, .-dummy
Since you're on a thumb-only CPU you don't need thumb interworking via bx lr
, but as @old timer points out: if you can leave LR untouched during your function then you can just return with bx lr
instead of popping it back into PC.
Also note that the first arg is passed in R0, so reading R3 is reading a register that your prototype says is not an input.
Moving this to a stand-alone asm file is totally fine, just as valid, and probably a better choice. But since you asked about doing it with a naked
function, that should also work.