Instrucciones de Carga y Almacenamiento en Memoria
Estas instrucciones permiten cargar o almacenar un registro desde o hacia la memoria, todas las instrucciones de procesamiento de datos realizan operaciones aritméticas y lógicas pero siempre entre registros, en el momento de requerir realizar estas operaciones entre variables, deberemos primero cargar las mismas desde la memoria con una instrucción de Carga en Memoria, realizar las operaciones aritméticas o lógicas requeridas siempre entre registros y finalmente guardar los resultados en memoria mediante una instrucción de Almacenamiento en Memoria.
La arquitectura ARM soporta dos tipos de instrucciones de carga y almacenamiento de un registro.
- Cargar o Almacenar un word (32bits) o un byte sin signo (8bits)
- Cargar o Almacenar medio word sin signo o con signo (16bits) o extender un byte con signo. (todas las operaciones que operan con signo, se refieren únicamente a operaciones de carga no de almacenamiento)
En ambos tipos de instrucciones, siempre existe un registro base y un offset para formar la dirección de la memoria.
Registro base, puede ser cualquier registro de propósitos generales, incluyendo el PC, esto permite acceder en forma relativa al PC y hacer al código independiente de la posición en donde se ubique.
Offset o Corrimiento, tenemos varias alternativas
Inmediato, el offset es un numero sin signo, el cual puede ser sumado o restado al registro base, el offset inmediato se usa para acceder a datos que están a una distancia fija del comienzo de los datos.Para el caso de acceso a word sin signos o bytes el offset es un numero de 12 bits, para el caso de medio word o bytes con signo, el numero es de 8 bits.
Registro, el offset es cualquier registro de propósitos múltiples (excepto en PC), este registro puede ser sumado o restado al registro base, este método es muy usado para acceder a array o vectores.
Registro escalado, el offset es un registro de propósitos múltiples, desplazado una cantidad fija de bits, el valor resultante, es sumado o restado al registro base, el método de desplazamiento es el mismo utilizado en las instrucciones de procesamiento de datos, siendo el desplazamiento a la izquierda el mas utilizado, lo que permite acceder de esta forma a array de estructuras, escalando el offset por el tamaño de la estructura.Los registros escalados, solo pueden utilizarse en instrucciones para acceso a word o bytes sin signo.
Además el offset y el registro base, interactúan de tres formas distintas.
Direccionamiento por corrimiento, la dirección de memoria está formada por la suma o resta del corrimiento con el registro base.
Direccionamiento pre-indexado, la dirección de memoria está formada de la misma forma que la anterior, pero esta dirección de memoria calculada, es escrita luego en el registro base.
Direccionamiento post-indexado, se toma el dato de la dirección apuntada por el registro base y luego se actualiza este sumándole o restándole el corrimiento. IMPORTANTE en este modo, si el offset es un registro, este nunca puede ser el mismo que el registro destino, los resultados en este caso son impredecibles.
Carga y Almacenamiento de word o bytes sin signo
Son las instrucciones que:
Cargan un valor simple de la memoria de tamaño word o byte y lo escriben en un registro de propósitos generales.
Almacenan el valor que posee un registro de propósitos generales a la memoria ocupando un byte o un word.
Tienen el siguiente formato.
LDR||STR{cond}{B}{T} Rd,dirección
cond indica la condición para ejecutar la instrucción.
B indica si opero con Byte en lugar de Word
T indica si el acceso se efectúa con los privilegios de user, esto permite desde cualquier modo con privilegios acceder a memoria simulando un privilegio restringido (User Mode), este modo únicamente esta habitado para el modo de direccionamiento post-indexado
Rd Registro destino
dirección está formada por el registro base y el offset.
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
09 |
08 |
07 |
06 |
05 |
04 |
03 |
02 |
01 |
00 |
cond |
0 |
1 |
I |
P |
U |
B |
W |
L |
Rn |
Rd |
dirección |
Bit I método de direccionamiento
Bits P,U,W dependen del tipo de direccionamiento
Bit L Carga L = 1 Almacenamiento L = 0;
Bit B Byte (B=1) y word (B=0)
Rn Registro base
Rd Registro donde se guarda el valor o desde donde se toma el valor a escribir
Carga y Almacenamiento de medio word y bytes con signo
Realiza la misma operaciones que la anterior, pero esta vez utilizando medio word o bytes con signo.
LDR||STR{cond}H||SH||SB Rd,dirección
cond indica la condición para ejecutar la instrucción.
H indica que opero con medio word sin signo
SH indica que opero con medio word con signo
SB indica que opero con byte con signo
Nota: el modificador SH y SB son solo para instrucciones de Carga (LDR)
Rd Registro destino
dirección está formada por el registro base y el offset
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
09 |
08 |
07 |
06 |
05 |
04 |
03 |
02 |
01 |
00 |
cond |
0 |
0 |
0 |
P |
U |
I |
W |
L |
Rn |
Rd |
dirección |
1 |
S |
H |
1 |
dirección |
Bit I Método de direccionamiento
Bits P,U,W dependen del tipo de direccionamiento.
Bit L Carga L = 1 Almacenamiento L = 0;
Bit S S = 1 indica una operación con signo S = 0 indica operación sin signo
Bit H H = 1 indica operación con medio word y H = 0 indica operación con bytes
Nota: El estado de estos bits se determinarían mediante los prefijos H = medio word, SH = medio word con signo y SB = byte con signo, otra designación como por ejemplo S = 0 y H = 0 el cual indicaría byte sin signo en realizad no existe como instrucción, se debe usar para esto la instrucción de carga y almacenamiento de word o bytes sin signo, esto ocurre también con el intento de utilizar operaciones de almacenamiento con signo
Rn Es el registro base
Rd especifica el registro a ser cargado o almacenado.
direccionamiento
Modo de direccionamiento
Los doce bits menos significativos pueden configurarse de tres formas distintas
El bit 25 o I indica el tipo de offset
- I = 1 offset inmediato
I = 0 offset por registro o por registro escalado.
Inmediato
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
09 |
08 |
07 |
06 |
05 |
04 |
03 |
02 |
01 |
00 |
cond |
0 |
1 |
1 |
P |
U |
B |
W |
L |
Rn |
Rd |
offset de 12 bits |
Instrucciones de word y bytes sin signo: como vemos el offset solo puede tener una longitud máxima de 12 bits
Instrucciones de medio word y bytes con signo: los bits 4 a 7 tiene otro uso, y no son usados como offset, por lo tanto el espacio del offset se reduce a 8 bits ( 0 a 3 y 8 a 11)
Offset por registro escalado
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
09 |
08 |
07 |
06 |
05 |
04 |
03 |
02 |
01 |
00 |
cond |
0 |
1 |
0 |
P |
U |
B |
W |
L |
Rn |
Rd |
cantidad shift |
shift |
0 |
Rm |
Instrucciones de word y bytes sin signo: Los bits 5 y 6 indico el tipo de offset y en 7 a 11 la cantidad de bits a correr.
Instrucciones de medio word y bytes con signo: no existe este modo con estas instrucciones.
Offset por registro
31 |
30 |
29 |
28 |
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
19 |
18 |
17 |
16 |
15 |
14 |
13 |
12 |
11 |
10 |
09 |
08 |
07 |
06 |
05 |
04 |
03 |
02 |
01 |
00 |
cond |
0 |
1 |
0 |
P |
U |
B |
W |
L |
Rn |
Rd |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
Rm |
Instrucciones de word y bytes sin signo: Es un caso particular del anterior, donde los bits correspondiente al shift ( tipo y cantidad ) están en cero indicando la ausencia de corrimiento.
Instrucciones de medio word y bytes con signo:funciona de la misma manera que las instrucciones de word y bytes sin signo.
Tipo de direccionamiento
Como vimos anteriormente existen un grupos de bits que indican de que manera se vincula el offet con el registro base
bit P indica si la operación de suma o resta entre registro base y offset, se realiza antes de acceder a la memoria
- P = 0 se accede y luego se suma o restan los operadores, corresponde a direccionamiento post-indexado
- P = 1 se suma o resta los operadores y luego se accede a memoria corresponde a Direccionamiento por corrimiento o Direccionamiento pre-indexado
bit U indica la operación entre base y offset
- U = 0 se suman los operadores
- U = 1 se restan los operadores
bit W tiene dos funciones
en el caso de P = 0 o sea direccionamiento post-indexado
- W = 0 acceso normal a memoria
- W = 1 acceso sin privilegios (modo usuario) corresponde al modificador T (LDRT,STRT, etc)
en el caso de P = 1 indica si actualiza o no el registro base (el caso de post-indexado siempre actualiza el registro base)
- W = 0 el registro base no se actualiza Direccionamiento por corrimiento
- W = 1 el registro base es actualizado Direccionamiento pre-indexado
Tabla de direccionamiento
Teniendo los modos de direccionamiento y los bits que definen el tipo de direccionamiento, podemos realizar una tabla que defina todos los modos y tipos de dirección que son posibles dependiendo del tipo de instrucción y de operaciones restringidas (modificador T) o no.
IWB = Instrucciones de carga y Almacenamiento de word y bytes sin signo.
IHB = Instrucciones de Carga y Almacenamiento de medio word y bytes con signo.
IWB |
IHB |
Modo |
Descripción |
Ejemplo |
|
con T |
sin T |
|
|
|
|
|
X |
|
[<Rn>, #+/-<offset_12>] |
offset inmediato |
LDR R1,[R2, #+1024] |
|
|
X |
[<Rn>, #+/-<offset_8>] |
offset inmediato |
LDR R1,[R2, #+100] |
|
X |
X |
[<Rn>, +/-<Rm>] |
offset por registro |
LDR R1,[R2, R3] |
|
X |
|
[<Rn>, +/-<Rm>, <shift> #<shift_imm>] |
offset por registro escalado |
LDR R1,[R2, -R4, LSL 3] |
|
X |
|
[<Rn>, #+/-<offset_12>]! |
offset inmediato pre indexado |
LDR R1,[R2, #-1024]! |
|
|
X |
[<Rn>, #+/-<offset_8>]! |
offset inmediato pre indexado |
LDR R1,[R2, #+100]! |
|
X |
X |
[<Rn>, +/-<Rm>]! |
offset por registro pre indexado |
LDR R1,[R2, -R4]! |
|
X |
|
[<Rn>, +/-<Rm>, <shift> #<shift_imm>]! |
offset por registro escalado pre indexado |
LDR R2,[R4, R3, LSL 3]! |
X |
X |
|
[<Rn>], #+/-<offset_12> |
offset inmediato post-indexado |
LDR R1,[R2],#+1024 |
|
|
X |
[<Rn>], #+/-<offset_8> |
offset inmediato post-indexado |
LDR R1,[R2], #+100 |
X |
X |
X |
[<Rn>], +/-<Rm> |
offset por registro post-indexado |
LDR R1,[R2],R3 |
X |
X |
|
[<Rn>], +/-<Rm>, <shift> #<shift_imm> |
offset por registro escalado post-indexado |
LDR R1,[R2],R3, LSL #2 |