AnsweredAssumed Answered

r3 reset when return from ISR

Question asked by robison.don on Sep 27, 2013
Latest reply on Sep 28, 2013 by Clive One
I have a really baffling problem.  Perhaps it is not even a problem.  It's just something I noticed when debugging my program.  Register 3 goes to it's reset value when I return from an interrupt service routine.  I am pushing r0-r2 and later popping them, and am returning by using the bx lr command.  On this last command, bx lr, return to before interrupt flag, r3 is reset.

Is it supposed to do this?  I don't want to avoid using register 3 through all my program, just in case an interrupt occurs and it gets reset.

Example code follows.

@@@ Directives
        .thumb                  @ (same as saying '.code 16')
        .syntax unified

@@@ Equates

        .equ STACKINIT,                   0x20005000
        .equ NVIC_ISER1,                 0xE000E104              @ This register is used to enable the global ethernet interrupt
        .equ NVIC_ISPR1,                 0xE000E204              @ This register is used to enable the global ethernet interrupt
        
.section .text
        .org 0

@@@ Vectors
vectors:        
        .word STACKINIT         @ stack pointer value when stack is empty
        .word _start + 1        @ reset vector (manually adjust to odd for thumb)
        .word _nmi_handler + 1  @
        .word _hard_fault  + 1  @
        .word _memory_fault + 1 @
        .word _bus_fault + 1    @
        .word _usage_fault + 1  @
    
        .org 0x0134
        .word _Ethernet + 1        @ Ethernet recieve a packet interrupt, start parsing

.org 0x0256        
_start:

        ldr r0, = NVIC_ISER1    @ this enables the Ethernet to interrupt the core
        ldr r1, = 0x20000000    
        str r1, [r0]                
        
loop:

        ldr r0, = NVIC_ISPR1    @ this enables the Ethernet to interrupt the core
        ldr r1, = 0x20000000    
        str r1, [r0]        
        
        b loop                 @ continue forever

_dummy:                        @ if any int gets triggered, just hang in a loop
_nmi_handler:
_hard_fault:
_memory_fault:
_bus_fault:
_usage_fault:

        b _dummy

_Ethernet:
        
        push {r2}
        push {r1}
        push {r0}        

        ldr r3, = 0x10101010    @ let don see if it worked.        

        pop {r0}
        pop {r1}
        pop {r2}        
        bx  lr   

Outcomes