From ARMwiki
(Difference between revisions)
Jump to: navigation, search
m (Added anchor to 32bittest program.)

Revision as of 07:11, 16 June 2011

Processor registers, simple.
The ARM offers, ostensibly, sixteen registers, R0 to R15. All registers are 32 bit values.

Of these registers, only two have specific purposes.

  • R15 is the Program Counter.
  • R14 is set to the return address upon executing a BL instruction.

Various conventions exist which place other specific uses on registers (such as R13 being the Stack Pointer), however the ARM itself does not place any requirements onto other registers.

If you are writing user mode programs: this, plus the applicable convention, is about all you need to know.

The complete register set

The reality, however, is that the ARM offers thirty seven registers. Thirty one of these are the general purpose registers, named R0 to R15. This is possible because which registers you see depends upon what processor mode you are in. The remaining six registers are status registers, and their visibility depends upon the current processor mode.

In general, R0 to R12 are the same, except when in FIQ mode where R8 upwards are shadow registers. R13 and R14 change depending upon the processor mode, with the exception of the two lowest privileged (User and System). The status register CPSR is the same across all modes, however all modes except User and System introduce a SPSR status register which is specific to that mode.

A diagram should make this clearer:

Processor registers, complete.

APCS registers

The Arm Procedure Call Standard defines names for the various registers, as follows:

Register APCS name Purpose
R0 a1 Argument registers, passing values, don't need to be preserved,
results are usually returned in R0
R1 a2
R2 a3
R3 a4
R4 v1 Variable registers, used internally by functions, must be preserved if required
R5 v2
R6 v3
R7 v4
R8 v5
R9 v6
R10 sl Stack Limit / stack chunk handle
R11 fp Frame Pointer, contains zero, or points to stack backtrace structure
R12 ip Procedure entry temporary workspace
R13 sp Stack Pointer, fully descending stack, points to lowest free word
R14 lr Link Register, return address at function exit
R15 pc Program Counter

Upon function return (by pushing lr into pc), v1-v6, sl, fp, and sp must be the same as they were on entry.

The APCS standard is defined in the RISC OS Programmers Reference Manuals on p4-399.

26 bit operation

The original ARMs (ARM2, ARM3) were simpler, and supported only four processor modes with correspondingly fewer registers.

The "26 bit" in the name is defined from the Program Counter being only 26 bits wide, thus permitting R15 to hold also the status flags. While this system worked well, and allowed one simple instruction to restore all stacked registers and exit the function, it was greatly limited by the fact that 26 bits only permits addressing of 64MiB. When the ARM was designed in the late '80s, this was a massive amount of memory (in fact, no MEMC (memory controller chip)) is capable of addressing more than 4MiB, and since using multiple MEMCs was often quirky, the majority of Archimedes machines contain no more than 4MiB, and I have not seen any with more than 8MiB.

For RISC OS machines of Acorn era, the register set is as follows:

Processor registers, older 26 bit.

Because the RiscPC processors work in 26 bit and 32 bit mode (to allow more than 64MiB to be used), things are somewhat more complicated. However as an end user, you can assume that RISC OS will appear to function in a 26 bit way (with individual tasks limited in the amount of memory that can be addressed). You will, however, need to read the relevant Technical Reference Manual if you plan to write IRQ or FIQ mode.

By way of example, here is a short program to enter 32 bit mode (under a mostly 26 bit RISC OS), set the Z flag, return back to 26 bit mode, and test if the Z flag is set. This should be run on a RiscPC, A7000(+), Mico, etc running RISC OS version 3.5 or later. It will not work on the Iyonix.

  REM >32bittest
  REM Short example to go into 32 bit mode, set the
  REM Z flag, and return to a conditional based upon
  REM this.
  REM From:
  REM We need to ensure the required hardware is present...
  emsg$ = "Sorry, you'll need a RiscPC or later, with a 32 bit capable "
  emsg$+= "processor in order to use this software."
  ON ERROR SYS "OS_PrettyPrint", emsg$ : PRINT : END
  SYS "OS_Memory", 6
  DIM code% 1024
  PRINT "Assembling code"
  FOR l% = 0 TO 2 STEP 2
    P% = code%
    [  OPT l%
       EXT 1                      ; Enable ExtBASICAsm
       \ Preserve our R14 and then enter SVC mode
       STMFD   R13!, {R14}
       SWI     "OS_EnterOS"
       ADR     R0, entering
       SWI     "OS_Write0"
       SWI     "OS_NewLine"
       \ Turn off all interrupts, because RISC OS won't be expecting 32 bit mode!
       SWI     "OS_IntOff"
       \ User32 code
       MOV     R0, #%10011
       MSR     CPSR_all, R0       ; Select CPSR mode, clear all the bits
       MOV     R0, R0
       MRS     R0, CPSR_all       ; Read CPSR
       BIC     R0, R0, #&F0000000 ; Clear the flag bits
       BIC     R0, R0, #&1F       ; Clear the mode bits
       ORR     R0, R0, #1<<30     ; Set the Z flag
       ORR     R0, R0, #%11       ; Set SVC26 mode
       MSR     CPSR_all, R0       ; Do it!
       MOV     R0, R0
       \ Turn interrupts back on again.
       SWI     "OS_IntOn"
       ADR     R0, exiting
       SWI     "OS_Write0"
       SWI     "OS_NewLine"
       \ If Z set, print Z set else print Z unset
       ADR     R0, zunset
       ADREQ   R0, zset
       SWI     "OS_Write0"
       SWI     "OS_NewLine"
       \ Return to USR mode
       BIC     R14, PC, #3
       TEQP    R14, #0
       MOV     R0, R0
       \ And get out of here.
       LDMFD   R13!, {PC}
       EQUS    "  Z flag is not set (this ain't right!)"
       EQUB    0
       EQUS    "  Z flag is set (as expected!)"
       EQUB    0
       EQUS    "  About to enter 32 bit mode, cross your fingers!"
       EQUB    0
       EQUS    "  Returned to 26 bit mode. Phew!"
       EQUB    0
  PRINT "Executing code"
  CALL code%
  PRINT "Finished"
Personal tools