Topic : RC51 / inline assembly and interrupt context saved

Forum : 8051

Original Post
Post Information Post
December 13, 2007 - 8:15pm
Guest

I tried to streamline a small interrupt routine using inline assembly (#pragma ASM/ENDASM). However there turns out to be a price for this. RC51 now stacks the entire 8051 register set, even if the #pragma ASM/ENDASM is empty. I guess this is because RC51 determines register usage and what to push while generating assembler, rather than after. So if after that it sees #pragma ASM it doesn't look inside the block but instead presumes that any register might be used.

Interrupts are one of the few places where I consider using assembly over C. The extra overhead of calling interrupts negates the advantages assembly has there. Is there any way of dealing with this?

regards Steven Pruzina

Replies
Post Information Post
+1
0
-1
January 16, 2008 - 10:18am
Guest

Hi guys,
iam also looking for a way to decativate the "automatic register stacking" on interrupts.
Is there something available within the yearly BN747_51 service release?

Kind regards,
Sören

+1
0
-1
January 21, 2008 - 5:00pm
Guest

The registers are stacked when PSW (register bank index) is not modified, i.e. when the "using N" attribute is not specified.
The best solution often consists in associating one bank of registers to one priority level of interrupts. Typically, for the devices with 2 priority levels, 3 banks are needed (one for the "main" level, and two for the interrupts.

When using #pragma ASM/ENDASM, the assembly code is not analysed, and RC51 will consider that all registers are potentially modified (as when calling an external function). But the use of the "using N" attribute is always the best solution.

+1
0
-1
January 23, 2008 - 9:31pm
Guest

Thanks. I didn't think of switching banks. That will work fine.

Steven Pruzina

+1
0
-1
January 28, 2008 - 8:35am
Guest

Me either...
Normally the RC51 works as follows if i declare the following line in C:

void SerialInt(void) interrupt 4
{
...
}

In ASM the code looks as follows:

0023 push ...
002x push ...
002x push ...
00xx ...
003x pop ...
003x pop ..
003x pop ...
003x reti

But i would like to have an option (like SDCC has), where iam able to say the code looks as follows:

void SerialInt(void) interrupt 4 sampleoption
{
...
}

This option make RC51 to generate only the following code:

0023 RETI

I want to have the possibility to handle the code in the interupts as i want. Because in some applications i know exactly which registers i need to store and what i want to do....
When writing a flashloader and you define a redirectable interrupt, RC51 will push/pop always (independently of the infact used registers) everything he could use. RC51 stores then: ACC, PSW, DPTR, R1...R8. That makes 24 instructions (PUSH and POP instructions)...

at 0x08 data ISR_Redirect = 0x00;

void MasterISR(void) interrupt 4
{
if (!ISR_Redirect)
{
asm{0x12} // lcall
asm{ISR_04_RAPP_ASM}
} else
{
asm{0x12} // lcall
asm{ISR_04_RFLA_ASM}
}
}

Kind regards,
Soeren

+1
0
-1
January 28, 2008 - 11:09am
Guest

RC51 pushes only what is necessary to push (or all its work registers it does know because of call to the external function).
The standard way with interrupt handlers is to use the "using N" attribute in order to avoid the pushing of the registers.
Now, if you wish to write the complete body of the interrupt in assembly, the best consists in wirting the whole function in assembly.