Loading the desired table entry is performed by first loading the start
address of the table, then moving the immediate constant "4" into a
register, using the multiply and add instruction to calculate the address,
and finally loading the entry. However, this operation can be performed
by the barrel shifter more efficiently as follows:
; R0 holds the entry number [0,1,2,...]
LDR R1, =StartOfTable
MOV R3, #4
MLA R1, R0, R3, R1
LDR R2, [R1]
...
StartOfTable
DCD table data
In this code the barrel shifter shifts R0 left 2 bits (ie. multiplying it
by 4), this intermediate value is then used as the index for the LDR
instruction. Thus a single instruction is used to perform the whole
operation. Such significant savings can frequently be made by making good
use of the barrel shifter.
; R0 holds the entry number [0,1,2,...]
LDR R1, =StartOfTable
LDR R2, [R1, R0, LSL #2]
...
StartOfTable
DCD table data
The barrel shifter can perform the following types of operation:
-------------------------------------------------------- LSL |shift left by n bits; -------------------------------------------------------- LSR |logical shift right by n bits; -------------------------------------------------------- ASR |arithmetic shift right by n bits (the bits fed |into the top end of the operand are copies of the |original top (or sign) bit); -------------------------------------------------------- ROR |rotate right by n bits; -------------------------------------------------------- RRX |rotate right extended by 1 bit. This is a 33 bit |rotate, where the 33rd bit is the PSR C flag. --------------------------------------------------------
The barrel shifter can be used in several of the ARM's instruction classes. The options available in each case are described below.
STR R7, [R0], #24 ;Post-indexed
LDR R2, [R0], R4, ASR #4 ;Post-indexed
STR R3, [R0, R5, LSL #3] ;Pre-indexed
LDR R6, [R0, R1, ROR #6]! ;Pre-indexed + Writeback
In the pre-indexed instructions the offset is calculated and added to the base. This address is used for the transfer. If writeback is selected, then the transfer address is written back into the base register.
In the post-indexed instructions the offset is calculated and added to the base after the transfer. The base register is always updated by post-indexed instructions.
ADD R0, R1, #&C5, 10
MOV R5, #&FC000003
ADD R0, R1, R2
SUB R0, R1, R2, LSR #10
CMP R1, R2, R1, ROR R5
MVN R3, R2, RRX
The following cover loading constants into registers, and explain how armasm can help out the assembly language programmer: