0
\$\begingroup\$

Undefined exception in ARM processors is described as being taken when the processor encounters an instruction that is undefined or not supported by implementation.

I am not able to understand that processor is in this mode is either due to program portability or due to the wrong instruction of some program which is not part of instruction sets of processor?

\$\endgroup\$
  • \$\begingroup\$ Trying to execute a floating point instruction in cortex M3 \$\endgroup\$ – Umar Mar 10 '17 at 17:28
  • \$\begingroup\$ @Umar actually my question is about undefined mode why processor comes in that mode? Is that portability issue or instruction issue? \$\endgroup\$ – Shubham Mar 10 '17 at 17:29
  • \$\begingroup\$ This usually happens when a program jump is made to the wrong address due to a coding error. \$\endgroup\$ – Trevor_G Mar 10 '17 at 17:39
  • \$\begingroup\$ @Shubham: your question is not clear at all. What is "portability issue"? What is "instruction issure"? Can't a portability issue be an instruction issue? \$\endgroup\$ – Curd Mar 10 '17 at 17:42
  • \$\begingroup\$ @Curd by portability issue i mean when i write a code for particular processor and then same code i try to port on another processor with minimalist changes or doesn't require any major change then it will run on that processor also without any error. Does during porting to another processor it will cause processor to switch into undefined mode??? \$\endgroup\$ – Shubham Mar 10 '17 at 17:45
4
\$\begingroup\$

The processor enters "undefined mode" when it encounters an invalid instruction.

Not all possible bit patterns are valid instructions, and contrary to older processors where at least something happens, the processor detects these patterns and then generates an exception.

The handler for this exception is executed normally, but the processor mode is changed so that the R13_und and R14_und registers are mapped to R13 and R14. This is necessary because the handler requires a local stack and information about the faulting address.

The stack for the handler needs to be separate because it is not guaranteed that the code currently running has a valid stack. Simply using whatever R13 contained at this point would be a security issue, as the handler executes with supervisor privilege. Thus, the operating system at start reserves stack space for the Undefined handler and places the stack top address in R13_und (by switching to UND mode briefly):

    mrs r0, cpsr
    bic r1, r0, #0x1f
    orr r1, r1, #MODE_UND
    msr cpsr_c, r1
    ldr r13, =_und_stack_top
    msr cpsr_c, r0

The R14 register is also shadowed, because it is overwritten at exception entry, but the handler may decide to emulate the offending instruction and return to regular program flow, which would require restoring R14 (for which a stack would be required, which again is not guaranteed).

For example,

    bl  do_something
    ...

do_something:
    vstm r13!, {s3}
    ...
    vldm r13!, {s3}

The do_something function stores s3 on the stack, because it modifies it and wishes to restore it at the end, but doesn't save r14, because it doesn't call any subroutines. If the CPU doesn't have an FPU, the Undefined handler gets called for the vstm instruction.

Actual exception vector:

undefined:
    b undefined_handler

Handler:

undefined_handler:
    stm r13!, {r0-r4,r14}  // this goes on the UND handler stack
    ldr r0, -8[r14]        // look at the offending instruction
    ...                    // emulate instruction
    ldm r13!, {r0-r4,r14}  // restore everything from stack
    subs r15, r14, #8      // return from exception

The r14 value for do_something was hidden in the r14_USR register, which is not accessible from Undefined mode -- if the handler were interested in that, it would change to System mode (which is a privileged mode with access to USR registers), copy the value to another register and switch back to UND mode in order to get access to its own stack back.

\$\endgroup\$
  • \$\begingroup\$ very well explained, got the overall idea in what circumstances processor switch into undefined mode. \$\endgroup\$ – Shubham Mar 10 '17 at 18:18
  • \$\begingroup\$ Entertainingly, some instructions (when conditional) are only undef if the condition code passes. This is handy for floating point instructions. \$\endgroup\$ – Sean Houlihane Mar 29 '17 at 17:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.