Hullo guys , I had to write my own assembly subroutines to be called from C files . From the ARM Cortex-M documentation , it's clear that when an interrupt occur , only R0->R3 , R12 are pushed into stack . So for safe operation , those 're the only registers allowed to be used when interrupts 're enabled ?
thx for ut reply K mangunese , But what u mean preserve them ? , if i use them , then an interrupt occurs , they will be corrupted at the return from the ISR n their values will be lost.
The interrupt handler is responsible for protecting the registers.
The procesor itself has a limited set of registers it will push before entering the ISR. But the ISR may itself continue to push more registers and so may also make use of more registers.
It's the same for standard C. When a C function calls another C function, then the called function is allowed to play around with some registers without needing to explicitly save them. If it needs to use more registers, then the C function must push the extra registers before using them, so it can restore their original content before returning.
thx Per Westermark , u r right , so what is the best way to do that ? Inline Assembly at the beginning and end of the ISR ?
The reason you don't need any "isr" keyword for ISR handlers is that you don't need to do anything. The processor pushes the minimum set of registers to make the interrupt service routine "compatible" with normal C functions. And the compiler will push any additional registers just as it has do do for any other C function.
That's a reason why you can get away with using zero assembler. Before the Cortex chips, you needed assembler both to set up an initial stack, and to handle the save of some state information for interrupts.
So stay away from assembler unless you have very special needs.
I see ur point Per Westermark , but i really need it , as this subroutine will perform some DSP algorithms . Well , I guess i will try my best not to use more than those 5 registers who r saved before the ISR . Thats sth really bad about the Cortex-M , though it saves the state for the whole FPU registers .
You think it's bad that the Cortex-M saves a number of registers? Most processors hardly save any state at all...
You do not want a processor that saves all state to memory, since saving state consumes memory bandwidth and affects latency. So the only solution is to have complete register banks to switch between. But not easy to do either in case you want nested interrupts - then each interrupt nesting needs one more register bank.
In the end, the compiler will have to save extra registers in case of a C function. And the developer - you - will have to save extra state in case of an assembly-written routine.
Well , I guess i will try my best not to use more than those 5 registers who r saved before the ISR
It sounds like you haven't understood the situation.
Your ISR must save any extra registers required, just as it would have to do for a normal C routine. If you follow this very simple rule, you can use any registers you want.
Compared to some processors, the Cortex is a joy. People far smarter than me (and almost definitely the majority of the users of this forum) were involved in the design of it.
Don't knock it before you have at least a basic understanding of it.
well , Per Westermark , so the best thing is to push the rest of the registers at the very beginning of the ISR , and then pop them at the very end of it ? (the ISR will be in C) , or u have another better suggestion . >>> Thx in advance
If the ISR is in C, then the compiler's got you covered, it understands the register requirements, and pushes those registers that would otherwise get corrupted. On the Cortex parts you don't need the __isr directives, because unlike the ARM7/9 the Cortex has a unified calling conventions, with no hoops to jump through in IRQ/FIQ prologue/epilogue code.
If you do it in assembler, then yes you'd better understand how the processor works, and the concept of preserving the operating context when you interrupt it. This isn't an ARM unique concept.
Please pick up some manuals, and microprocessor texts, and study them.
Westonsupermare Pier , well I have been working with Cortex for quite 3 yrs now , but its my first time to encounter a situation in which I have to do some components in Assembly . I studied the Cortex-M4 programming manual provided by ST , and also the armasm User Guide but all that provided is the stacking frame . As u r saying its the work of the C compiler , so thats why I did not find much about it in those documentations . Thx for ur help man , and if u recommend further documentations , that would be nice .
The ARM documentation is very, very clear on what registers are preserved and what registers aren't. It's all in the ABI what a function may expect when being called, and what it may expect when calling some other function.
If you need three extra registers, you push three extra registers. Doing it at the start? Maybe. That depends on if you know that you always needs three extra registers. If the code maybe only needs them once every 10 calls then it's better to delay with saving them until your code performs that special magic that does need them. But decisions about what registers to use and when to save them is all part of "engineering", i.e. all the little decisions you need to do in your daily work based on your goals, your needs and the path you have decided to take to reach your goals.