A: |
There are two reasons for this. First, the sequence "do something here"
surely uses some local variables. The compiler will put them in
registers during the optimization, and it will generate code for
saving them on the stack at the beginning of the procedure, before the
execution of any statements in the function body. So, before executing
asm("movem.l %d0-%d7/%a0-%a6,-(%sp)");
something will be pushed on the stack. Read this as "open
brace '{' is not only the marker, it also generates an entry
procedure code". So, when "rte" is encountered, the return
address on the stack is trashed. Second, even if the
procedure does not use any local vars, the entry code for the
procedure is usually
link #something,%a6
and the stack is again not suitable for executing "rte".
Before release 2.2 of TIGCCLIB, the only universal and correct method for defining
interrupt handlers was is to define a pure assembly auxilary procedure as follows:
void InterruptHandler(void); // Just a prototype
asm ("myInterruptHandler:
move.w #0x2700,%sr
movem.l %d0-%d7/%a0-%a6,-(%sp)
jbsr MainHandler
movem.l (%sp)+,%d0-%d7/%a0-%a6
rte");
void MainHandler(void)
{
// Put everything you want here...
}
To make life easier, starting from release 2.2, I introduced a new language extension called
DEFINE_INT_HANDLER in the intr.h
header file. Now, it is enough to write
DEFINE_INT_HANDLER (myInterruptHandler)
{
// Put everything you want here...
}
|