Академический Документы
Профессиональный Документы
Культура Документы
Captulo 3.
Variables.
3.1. Definicin de datos enteros como variables globales.
El siguiente segmento ilustra una serie de definiciones de enteros inicializados. En C, se denomina definicin de datos, la instancia en que se asigna espacio en la memoria para las variables. Y se emplea declaracin cuando no existe asignacin de espacio en la memoria. Por ejemplo una declaracin extern, o bien la declaracin de una estructura. En C, los enteros ocupan una palabra, por definicin. Por ejemplo, en un PC, con determinado procesador, si un entero es de 16 bits, un long es de 32 bits. Por estar definidas fuera de una funcin, se las denomina variables globales. int i1 = 0x12345678; static int i2 = -1; const int i3 = 1; volatile int i4 = 8; short int i5 = 6; long int i6 = 7; int arr[] = {0,1,2,3}; int main(void) { return(0) ; } Al ensamblarlo, resulta para la zona de datos: .set reorder .globl i1 .sdata .align 2 i1: .word 0x12345678 .sdata .align 2
30-08-2008
i2: .word 0xffffffff # -1 en complemento a dos .globl i3 .sdata .align 2 i3: .word 0x1 .globl i4 .sdata .align 2 i4: .word 0x8 .globl i5 .sdata .align 1 # Ntese el alineamiento a medias palabras. i5: .half 0x6 .globl i6 .sdata .align 2 #Al volver a alineamiento de palabra, queda un espacio de un half i6: .word 0x7 .globl arr #Arreglos los localiza en segmento data .data .align 2 arr: .word 0x0 #Almacena las componentes secuencialmente. .word 0x1 # arr[1] en la direccin de palabra siguiente a la de arr[0]. .word 0x2 .word 0x3 A las variables se las localiza en memoria. Cada una de ellas queda asociada a una direccin en el segmento esttico de datos. Y al cargarlo en memoria, puede visualizarse la zona de datos segn: i1 es la direccin: 0x10010004 con contenido: 0x12345678 i2 es la direccin: 0x10010008 i3 es la direccin: 0x1001000C i4 es la direccin: 0x10010010
30-08-2008
Variables
i5 es la direccin vlida de media palabra: 0x10010014 La direccin 0x10010016, vlida para media palabra, se rellena con ceros y no es utilizada. Las medias palabras se ordenan little endian dentro de la palabra. La media palabra menos significativa tiene la direccin menor. i6 es la direccin: 0x10010018 con contenido 0x00000007. Se aprecia que SPIM, no hace diferencia entre el segmento para small data con el segmento data. Tampoco hay diferencias para variables calificadas constantes y voltiles. El calificador static se aplica por defecto a las variables globales en C. En MIPS tampoco hay diferencia entre un int y un long. Ambos son de 32 bits. La misma definicin podra haberse logrado en assembler, segn: .sdata i1: .word 0x12345678 i2: .word 0xffffffff i3: .word 0x1 i4: .word 0x8 .align 1 i5: .half 0x6 .align 2 i6: .word 0x7 .data .align 2 arr: .word 0x0, 0x1, 0x2, 0x3 Es importante destacar que las variables en assembler estn asociadas a una direccin. Las siguientes definiciones son para variables globales no inicializadas. int i1; int arr[4]; int main(void) { return(0) ; } Profesor Leopoldo Silva Bijit 30-08-2008
El ensamblador genera el siguiente cdigo a continuacin de main. .globl arr .comm arr,16 .globl i1 .comm i1,4 Donde .comm asocia el nombre con un nmero de bytes de un bloque comn de datos. En SPIM se almacenan los bloques comunes de datos en el segmento de datos. Pueden visualizarse las direcciones en que se localizan las variables no inicializadas con Simulator: Display symbol table: g g arr at 0x10010004 i1 at 0x10010014
En sistemas NT, SPIM no procesa los bloques comunes de datos. Si lo hace en XP y Windows 2000. Los datos no inicializados no se ven en la zona de datos, al cargarse el programa, en el caso del ejemplo, la zona se visualiza: Data Segment ========================= DATA [0x10000000]...[0x10040000]
0x00000000
30-08-2008
Inicialmente las globales, x e y tienen valores enteros 1 y 2 respectivamente. La primera asignacin, copia el valor de x en la variable y. Luego de la ejecucin de la asignacin la variable y tiene valor 1; la variable x no cambia su valor. Puede decirse que se lee x y se escribe en y. La segunda asignacin escribe en el espacio asociado a x, la constante 5. La tercera asignacin realiza una suma de dos constantes, y deposita el valor resultante en la variable y. La constante 0xFFFF ocupa 16 bits y su valor equivalente en decimal es 65535. Si se ensambla con lcc, la parte del texto que traduce las asignaciones es la siguiente: lw $24,x sw $24,y la $24,5 sw $24,x la $24,65537 sw $24,y El procesador MIPS permite el movimiento de contenidos de memoria hacia registros y viceversa. Para esto dispone de las instrucciones load word (carga registro con una palabra de memoria) y store word (almacena o guarda en una direccin de la memoria, el contenido de un registro). La instruccin assembler lw $24, x toma el contenido de la variable global x y la almacena dentro del registro temporal $24 (cuyo smbolo es $t8). Como veremos, es una macroinstruccin. La instruccin assembler sw $24, y guarda el contenido del registro temporal $24 en el espacio asignado a la variable y. Es decir, escribe el valor de $t8 en la direccin asociada a y. Como veremos, es una macroinstruccin. Si cargamos en la memoria, mediante SPIM, visualizamos la zona de datos y de programa, segn:
30-08-2008
Observamos que la variable global x, se almacena en la direccin: 0x1001004, y que la variable y est en la direccin: 0x10010008 Texto de la primera asignacin: [0x0040029c] 0x3c011001 [0x004002a0] 0x8c380004 [0x004002a4] 0x3c011001 [0x004002a8] 0xac380008 y = x; lui $1, 4097 lw $24, 4($1) lui $1, 4097 sw $24, 8($1)
En metodologa RISC, todas las instrucciones deben ocupar una palabra. Pero para especificar una direccin se requieren 32 bits. Y no es posible codificar el cdigo de operacin de la instruccin ms los 32 bits en una palabra. Para resolver esta dificultad se coloca en el repertorio de mquina a la instruccin: lui <registro>, <valor expresado en 16 bits> La cual carga en la parte ms significativa del registro, los 16 bits que se especifican, como dato inmediato, en la instruccin. Los 16 inferiores se rellenan con ceros. En el caso del ejemplo, el valor decimal 4097 equivale a 0x1001 en hexadecimal, que corresponden a la parte ms significativa de la direccin x. lui es load upper immediate En un caso general se emplea la instruccin: ori rt, rs, <inmediato de 16 bits> para colocar los 16 bits inferiores de una direccin en un registro. Ya que el ori efecta el or, bit a bit, del contenido del registro rs con el valor inmediato y el resultado se deposita en el registro destino. Al valor inmediato se lo rellena con 16 bits de ceros a la izquierda, para completar los 32 bits. La instruccin or inmediato setea los 16 bits inferiores, lui setea los 16 superiores. Por ejemplo, la secuencia: lui $t0, 0x1234 ori $t0,$t0,0x5678 escribe en $t0 el valor 0x12345678 Para efectuar los movimientos entre memoria y registros se disponen las instrucciones de mquina: lw rt, <offset>(rs) sw rt, <offset>(rs)
30-08-2008
Variables
Se emplea el mecanismo de direccionamiento: registro base + offset, para establecer la direccin de la celda de memoria en que lw leer su contenido y lo depositar en el registro rt; en la misma direccin sw escribir el contenido del registro rt. El offset es un valor con signo de 16 bits, que se escribe en un campo de la instruccin, y que expresa el nmero de bytes que deben ser sumados al contenido del registro rs, para obtener la direccin efectiva. La expansin de las macros se logra empleando el registro temporal $1 (en smbolo $at, el cual est reservado para uso del ensamblador). Zona de datos: x [0x10010004] y [0x10010008] Segmento instrucciones: lui $1, 0x1001 lw $t8, 4($1) lui sw $1, 0x1001 $t8, 8($1)
0x00000001 0x00000002
; lw
$t8, x
; sw
$t8, y
Luego de la asignacin la zona de datos globales queda: [0x10010000] 0x00000000 0x00000001 0x00000001 0x00000000 Un programador en assembler podra efectuar la asignacin y = x, en slo tres instrucciones. Para ello basta apuntar con un registro temporal a la zona global de datos, y luego leer la variable x a otro temporal; y desde ese registro escribir en la variable y. lui lw sw $t8, 0x1001 $t7, 4($t8) $t7, 8($t8) ; y=x
30-08-2008
Como comentario, hemos usado la notacin de C, para la indireccin. El asterisco que precede a un puntero, indica indireccin. Es decir el contenido de dicha direccin. El operador &, del lenguaje C, que precede a una variable, tiene por resultado la direccin de esa variable. En assembler, existe el macro: la $t8, x # t8 = &x que carga la direccin de una variable, en un registro (load address). Debe recordarse que en assembler los rtulos que identifican a las variables, son direcciones. Antes vimos que este macro se expande en la secuencia de lui, seguida de ori. Un esquema de las variables y valores, en ambiente assembler, muestra el par de registros involucrados y una variable global, ubicada en memoria.
Figura 3.1. Esquema de variables. En lenguaje C, si p es un puntero a entero y x es un entero, la asignacin: p = &x; /* direccionar */ Escribe en p, la direccin de la variable x. Debe definirse: int *p; La expresin: *p hace referencia al contenido de lo apuntado por p. El programador en C, ve dos variables, el puntero a entero p, y el entero x. Si graficamos a las variables como casilleros con el nombre de la variable en la parte superior, lo que queda dentro de la casilla es el contenido o valor de la variable.
30-08-2008
Variables
p &x
x *p
Figura 3.2. Punteros notacin.
Lo que C modela con tomar la direccin de una variable, e indireccionar respecto de un puntero, son las capacidades de direccionamiento indirecto disponibles en assembler.
Viendo en SPIM, el cdigo de mquina asociado a la macro la $24, 5 ; observamos que lo expande segn: ori $24, $0, 5 cuyo cdigo binario es: 0x34180005 Donde se ha destacado que el valor inmediato es un nmero que se expresa con 16 bits, en un campo de la instruccin binaria. En forma equivalente podramos usar: addi $24, $0, 5 Que efecta el add del valor inmediato con el registro cero, y lo deposita en $24. Si se hubiera asignado una constante negativa: x = -5. El cdigo generado por lcc para esta asignacin es la $24, -5 sw $24, x La macro: la $24, -5 , al ser cargada por SPIM, se interpreta con la secuencia: lui $1, -1 # extiende a 32 bits, con signo ori $24, $1, -5 Que podra ser reemplazada por solo una instruccin: addi $24, $0, -5
Sin embargo si la constante no puede ser expresada con 16 bits, se emplea la secuencia lui seguida de un ori, explicada antes. Este es el caso de la asignacin: y = 0xFFFF+2; El resultado de la expresin, en hexadecimal es: 0x10001, que no puede ser expresada en 16 bits.
30-08-2008
10
Que es traducida por lcc en: la $24, 65537 sw $24, y Ntese que lcc efecta operaciones aritmticas al ensamblar. Y la macro la $24, 65537 es expandida por SPIM en: lui ori $1, 1 $24, $1, 1 ; la $24, 65537
; 24: lw $24,x ; 25: la $24,2($24) ; 26: lw $15,y ; 27: la $15,1($15) ; 28: subu $24,$24,$15 ; 29: sw $24,z
Ntese que la macro: la $24, 2($24) es cargada como addi $24, $24, 2 Similar situacin ocurre para formar y+1. Permite cargar un registro con la suma del valor en un registro ms un offset. Aparece una nueva instruccin aritmtica:
30-08-2008
11
12
Entonces en los registros s, pueden almacenarse en forma segura las variables locales. Esto implica que los valores de variables locales, de una funcin, tienen los mismos valores antes y despus de un llamado a otra funcin. Este convenio se denomina: "el llamado salva las locales". La s del tipo le recuerda al programador assembler, que debe salvar dichos registros antes de usarlos. Sin embargo, si despus del llamado, la funcin que defini las locales, no las emplea, ser una prdida de tiempo el salvarlas. Para visualizar los conceptos anteriores, veremos una funcin en C y en assembler que emplee variables locales. Para simplificar veremos funciones que no tengan argumentos inicialmente. Luego agregaremos los argumentos. 3.6.1. Locales en registros. Usaremos en un primer ejemplo, variables locales definidas en la funcin principal main, y realizaremos una accin simple sobre las variables para visualizar la forma de acceso. int main(void) { register int x = 0, y = 1, z = 2; z = x + y; return(0) ; } El programador C, slo requiere visualizar sus variables locales, como casilleros con nombres. As entonces una vez dentro de la funcin se tiene:
x 0
y 1
z 2
x 0
y 1
z 1
30-08-2008
Variables Si se traduce a assembler, tendremos: .set reorder .globl main .text .align 2 .ent main main: .frame $sp,16,$31 addu $sp,$sp,-16 .mask 0x40c00000,-8 sw $22,0($sp) sw $23,4($sp) sw $30,8($sp) move $30,$0 la $23,1 la $22,2
13
# inicializa locales
addu $22,$30,$23
move $2,$0 L.1: lw $22,0($sp) lw $23,4($sp) lw $30,8($sp) addu $sp,$sp,16 j $31 .end main # valor de retorno # restaura registros s6, s7 y s8
# desarma frame.
sp
s6 s7 s8
offset
Figura 3.5. Frame de la funcin. El programador assembler visualiza el frame de la funcin. En el texto assembler, inmediatamente despus del punto de entrada, aparece la sentencia: .frame <reg1>, <nmero>, <reg2> Donde reg1 indica el registro puntero al frame, el nmero indica los bytes que tendr el frame, reg2 indica el registro que contiene la direccin de retorno. En lcc, se emplea el registro stack
30-08-2008
14
pointer, como reg1 y ra como almacn de la direccin de retorno. El nmero de niveles de stack es el nmero de bytes dividido por 4. Esta sentencia no genera directamente instrucciones de mquina, pero es una indicacin til para el programador assembler; en este sentido se denominan pseudoinstrucciones. Se emplean para depuradores de programas assembler. Luego viene la creacin del frame, mediante el cambio del stack pointer. Ntese que se resta, lo cual indica que la ocupacin del stack es desde direcciones mayores hacia direcciones menores; es decir crece hacia arriba, siempre que se asuma que las direcciones mayores estn hacia abajo. El stack pointer despus de la instruccin (addu $sp,$sp,-16) queda apuntando al tope del frame, esto se ilustra en el diagrama del frame. A continuacin, viene otra pseudoinstruccin, que le sirve al programador assembler como comentario, y cuyo uso est orientado a depuradores. .mask <mscara>, offset
Considerando 32 registros, se emplean ocho cifras hexadecimales, para codificar los registros que deben salvarse. Se marca con valor 1, cada uno de los registros que deben ser salvados en el frame. El bit 31 de la mscara corresponde al registro 31 y as correlativamente. El offset es la distancia en bytes, relativo al tope del frame anterior, donde se van guardando los registros; los registros con nmero mayor se almacenan ms hacia el fondo del frame.
3 1 r a 3 0 s 8 2 9 2 8 2 7 2 6 2 5 2 4 2 3 s 7 2 2 s 6 2 1 s 5 2 0 s 4 1 9 s 3 1 8 s 2 1 7 s 1 1 6 s 0 1 5 1 4 1 3 1 2 1 1 1 0 9 8 7 6 5 4 3 2 1 0
30-08-2008
Variables Luego de esto comienzan a existir las variables locales. Despus de toda esta actividad aparecen las acciones del bloque de la funcin. 3.6.2. Locales en registros y en el frame.
15
El siguiente ejemplo ilustra cmo se tratan las variables locales que no pueden ser almacenadas en registros s. Tenemos nueve variables locales que podemos almacenar en registros, la dcima se almacena en el stack. int main(void) { register int v1= 0, v2 = 1, v3 = 2, v4 = 4, v5 = 5, v6=6, v7=7, v8=8, v9=9, v10=10; v1 = v2 + v3; v10 = v10 + v1; return(0) ; } La variable global v10, a pesar que est precedida por la clase de almacenamiento registro, se trata de forma diferente. Es una celda del stack, ubicada en el fondo del stack, en este caso. El compilador asocia la direccin efectiva: -4+40($sp) a la variable local v10. La siguiente secuencia inicializa a v10: la $24,10 sw $24,-4+40($sp) Si se desea leer el contenido de v10 a un registro temporal, se emplea: lw $t8,-4+40($sp) Si se desea escribir en v10 desde un registro temporal, se emplea: sw $t8,-4+40($sp) Un esquema del frame:
30-08-2008
16
sp
offset
s0 s1 s2 s3 s4 s5 s6 s7 s8 v10
Figura 3.7. Frame con registros salvados y local. 3.6.3. Locales en el frame. En forma similar, si no se especifica register para las locales, stas son almacenadas en el stack, el siguiente ejemplo ilustra la situacin: int main(void) { int v1 = 0, v2 = 1, v3 = 2; v1 = v2 + v3; return(0) ; } Figura 3.8. Frame con locales. Se crea un frame de cuatro palabras. El compilador determina las siguientes direcciones efectivas para las variables: -4+16($sp) para v1; -8+16($sp) para v2; y -12+16($sp) para v3. Tratando a las locales en memoria, no se requiere salvar ni restaurar registros s, pero si iniciar las variables locales antes de usarlas; y esta operacin emplea accesos a memoria. Donde se presentan diferencias es en la manipulacin de las variables dentro del bloque de la funcin, ya que resulta ms eficiente, en tiempo, si las variables estn en registros. El texto que inicia las locales, ahora en memoria, es: sw $0,-4+16($sp) la $24,1 sw $24,-8+16($sp) la $24,2 sw $24,-12+16($sp)
sp
offset
v3 v2 v1
30-08-2008
Variables
17
An nos falta analizar la forma de tratamiento de los argumentos, pero ya podemos darnos cuenta del costo de administracin de una funcin. Cuando se busca la mxima velocidad es preferible evitar las funciones y emplear variables globales. Sin embargo esta alternativa lleva a programas difciles de mantener y depurar.
Variable Registro smbolo registro v8 $30 s8 v7 $23 s7 v6 $22 s6 v5 $21 s5 v4 $20 s4 v3 $19 s3 v2 $18 s2 v1 $17 s1 v0 $16 s0
Figura 3.9 Equivalencias entre variables y registros
30-08-2008
Texto assembler sll $s8,$s7,4 sra $s8,$s7,4 sra $s8,$s7,$s6 not $s7,$s6 and $s6,$s5,$s4 or $s5,$s4,$s3 xor $s7,$s6,$s5 sll $s6,$s5,1
Mnemnico shift left logical shift right arithmetic immediate shift right arithmetic register
Figura 3.10. Compilacin de corrimientos y operadores al bit. Ntese que existe una traduccin de una instruccin de alto nivel por una de mquina.
30-08-2008
Variables
19
ii) Las directivas: .word, .half y .byte establecen el tipo de la variable. Al mismo tiempo permiten iniciar con valores a las variables. Se denomina segmento esttico de datos a la zona de la memoria en que se almacenan datos que permanecern vigentes durante toda la ejecucin de un programa. Tambin se dispone de un segmento dinmico de datos (en un stack) en el cual las variables se crean, se modifican y desaparecen, durante la ejecucin del programa. El segmento assembler siguiente, crea 6 variables de tipo palabra (v1 a v6), luego almacena una media palabra en la variable v7; seguida de un byte identificado por la direccin simblica o variable v8; despus un arreglo arr, de 6 palabras; finalmente un arreglo de caracteres o string. .data 0x10010000 #variables estticas v1: .word 0x10001000 v2: .word 0x20002000 v3: .word 0x30003000 v4: .word 0x40004000 v5: .word 0x50005001 v6: .word 0x60006000 v7: .half 0x1234 v8: .byte 0xFF .align 2 arr: .word 0,1,2,3,4,5 string: .asciiz "abcdef" Para minimizar el tiempo de acceso las variables de tipo palabra se almacenan alineadas, es decir comienzan en una direccin vlida de palabra. As entonces a v1 le corresponde la direccin 0x10010000 y a v6 le corresponde 0x10010014. En la palabra que comienza en 0x10010018 se almacena la media palabra y tambin cabe el byte, y an queda espacio para otro byte. Al no existir la necesidad de almacenar otro byte, debe asegurarse que la nueva variable est alineada segn su tipo. En el ejemplo, a continuacin del byte, se dispone un arreglo de palabras. Por esta razn se fuerza el alineamiento de palabra, con la directiva .align 2. Los mecanismos de direccionamiento de memoria permiten accesar a palabras, medias palabras y bytes, con una instruccin. El arreglo, de seis palabras, comienza entonces en la direccin: 0x1001001C. Luego un arreglo de caracteres, terminado automticamente por un carcter nulo (con valor 0x00), que comienza en la direccin: 0x10010034. Se carga en el simulador SPIM, el programa assembler anterior, y se muestra a continuacin el segmento esttico de datos, que permite confirmar las direcciones de las variables, que se han
30-08-2008
20
dado antes. Debe recordarse que las direcciones son de bytes, y que cada palabra tiene 4 bytes. Puede obtenerse un texto del ambiente del simulador, con el comando: File; Save log file. Data Segment [0x10010000] [0x10010010] [0x10010020] [0x10010030]
Para compactar el despliegue de los datos, se colocan cuatro palabras por lnea. De este modo las direcciones aumentan en diecisis senas (no en decenas), ya que se tienen 16 bytes en una lnea. El carcter a tiene cdigo ASCII 0x61, el f tiene cdigo 0x66. En el simulador, puede advertirse el orden de los bytes dentro de una palabra. As entonces, el carcter a est depositado en 0x10010034; el b en 0x10010035; el c en 10010036; el d en 0x10010037; el e en 0x10010038; el f en 0x10010039; y el carcter nulo, con que se termina el string en 0x1001003A. Este orden es little endian, ya que el byte ms derechista de una palabra tiene una direccin binaria que termina en 00. La variable, de tipo byte, v8 se encuentra en el byte 2 de la palabra ubicada en 0x10010018; es decir en la direccin: 0x1001001A. La variable v7, de tipo media palabra, se encuentra ubicada en direccin 0x10010018 y ocupa dos bytes. El valor 0x34 se almacena en 0x10010018 y el valor 0x12 en 0x10010019. 3.8.1. Manipulacin de palabras. Para cargar en un registro la variable v1 desde la memoria, debe tenerse en un registro la direccin de v1, pero sta ocupa 32 bits. Para ello se emplean dos instrucciones con direccionamiento inmediato; una que carga (16 bits) en la parte superior de un registro y otra que efecta un or con los 16 bits inferiores. Ejemplos: Los 16 bits ms significativos de la direccin de v2 son: 0x1001, y los 16 inferiores son 0x0004. Emplearemos el temporal $t1 para formar la direccin de v2. lui $t1, 0x1001 ori $t1, $t1, 0x0002 Los 16 bits ms significativos de la direccin de v1 son: 0x1001, y los 16 inferiores son 0x0000. Emplearemos el temporal $t1 para formar la direccin de v1. lui $t1, 0x1001
30-08-2008
Variables
21
No es necesario el ori, para cargar con ceros los 16 bits menos significativos ya la instruccin lui lo hace. Como la accin de fijar un registro como puntero a una palabra de la memoria, es una accin muy frecuente, los diseadores de SPIM crearon una macro instruccin que efecta la secuencia anterior, de modo ms simple, y en forma simblica. la $t1, v1 # t1 = &v1 carga direccin de v1 en t1.
La macro instruccin se denomina la, por load address. Para su ejecucin en Settings, debe estar deshabilitada la casilla bare-machine (se trabaja con la mquina virtual: la mquina sola ms el repertorio de macros). En este caso, el simulador reserva el registro $1(de nombre simblico at) para implementar las macros, cuando necesita almacenamiento temporal; de esta forma el programador no puede emplear dicho registro en su cdigo. Ahora la carga del valor de v1 en el registro temporal $t2, es simplemente: lw $t2, 0($t1) # t2 = *t1 indirecciona, va puntero.
Se ha empleado direccionamiento indirecto relativo a registro, empleando el modo base+offset nativo del procesador, con desplazamiento cero.
Para accesar la variable v2, u otra, puede emplearse un mecanismo similar al visto. Sin embargo resulta conveniente dejar apuntando con $t1 al inicio del segmento de datos y efectuar el direccionamiento con un offset relativo a $t1. Por ejemplo v2 est cuatro bytes ms adelante, v3 a 8 bytes. En un caso ms general, para este fin se provee de un registro especial denominado gp(con nmero decimal 28) global pointer, para apuntar a la zona esttica de datos. Entonces, la carga del registro $t3 con la variable v4, estando fijado el valor de $t1 con anterioridad, se logra con: lw $t3, 12($t1) # t3 = v4
3.8.2. Manipulacin de medias palabras. Veamos ahora el acceso a medias palabras. la $t4, v7 # t4 = &v7 lh $t5,0($t4) # t5 = *t4 que equivale a t5 = v7
30-08-2008
22
se ha trado la media palabra al registro $t5, y se ha rellenado con el bit ms significativo de 0x1234 (que es un cero y corresponde al bit del signo, como se ver ms adelante) las primeras 16 posiciones del registro $t5. Si se suma uno al contenido de $t5 y se vuelve a depositar en v7, mediante la secuencia: addi $t5, $t5, 1 # t5 ++ sh $t5, 0($t4) # *t4 = t5 equivale a v7 = t5 (t4 contiene la direccin de v7) Debe notarse que no se altera la variable v8 que comparte la palabra con v7. Cuestin que habra ocurrido si en lugar del store half se hubiese empleado sw. 3.8.3. Manipulacin de bytes. Veamos ahora el direccionamiento de bytes. Se genera cdigo para implementar v8 = v8-1 la $t6,v8 # t6 = &v8 lb $t7,0($t6) # t7 = *t6 o bien t7 = v8 addi $t7,$t7,-1 # t7-- o bien t7 = t7 1; esto debido a que no existe subi sb $t7,0($t6) # *t6 = t7, que equivale a v7 = t7 Debe notarse que la carga del byte, coloca en los 24 bits ms significativos de $t7, el bit del signo del byte en que est almacenada v8 (en este caso un uno). El almacenamiento del byte, no modifica el espacio de los otros bytes de la misma palabra. Sobre las direcciones de palabras, medias palabras y bytes: Supongamos que en la direccin 0x0010 tenemos una palabra, luego cuatro medias palabras, y finalmente ocho bytes. El espacio podra visualizarse: Direccin 0x0010 0x0014 0x0018 0x001C 0x0020 Contenido de las palabras de memoria de 32 bits Word1 Halfword1 Halfword0 Halfword3 Halfword2 Byte3 Byte2 Byte1 Byte0 Byte7 Byte6 Byte5 Byte4 Figura 3.11. Palabras, medias palabras, bytes. Las variables se han almacenado alineadas de acuerdo a sus tipos. La zona de medias palabras, con sus direcciones, puede visualizarse segn:
30-08-2008
23
Figura 3.12. Zona de medias palabras. Debe notarse el ordenamiento little endian, de las medias palabras. La zona de bytes, con sus respectivas direcciones, puede visualizarse segn: 0x001C 0x001D 0x001E 0x001F 0x0020 0x0021 0x0022 0x0023 Byte0 Byte1 Byte2 Byte3 Byte4 Byte5 Byte6 Byte7
Figura 3.13. Zona de medias palabras. As entonces, si el registro $t1 apunta a 0x0010, la variable Halfword0 puede referenciarse segn 4($t1); la Halfword1 por 6($t1). De igual forma, el Byte0 queda referenciado por 0xC($t1); el Byte4 por 0x10($t1). Si $t2 contiene 0x0020 el Byte3 puede direccionarse segn: -1($t2); el Byte6 por 2($t2). En direccionamiento base+offset, el desplazamiento es en bytes.
30-08-2008
24
ndice general.
CAPTULO 3. .............................................................................................................................................1 VARIABLES...............................................................................................................................................1 3.1. DEFINICIN DE DATOS ENTEROS COMO VARIABLES GLOBALES..........................................................1 3.2. ASIGNACIN. MOVIMIENTO DE DATOS ENTRE MEMORIA Y REGISTROS..............................................4 3.3. PUNTEROS. DIRECCIONAR E INDIRECCIONAR. ....................................................................................7 3.4. CONSTANTES. DIRECCIONAMIENTO INMEDIATO................................................................................9 3.5. EXPRESIONES SIMPLES CON VARIABLES GLOBALES Y CONSTANTES. ................................................10 3.6. VARIABLES LOCALES. FRAME. .........................................................................................................11 3.6.1. Locales en registros. ................................................................................................................12 3.6.2. Locales en registros y en el frame............................................................................................15 3.6.3. Locales en el frame. .................................................................................................................16 3.7. ACCIONES. CORRIMIENTOS. OPERADORES LGICOS AL BIT. ...........................................................17 Corrimientos y operadores al bit. ......................................................................................................18 3.8. ACCESO EN ASSEMBLER A VARIABLES DE DIFERENTE TIPO, EN SEGMENTO ESTTICO DE DATOS. .....18 3.8.1. Manipulacin de palabras. ......................................................................................................20 3.8.2. Manipulacin de medias palabras. ..........................................................................................21 3.8.3. Manipulacin de bytes. ............................................................................................................22 NDICE GENERAL. ....................................................................................................................................24 NDICE DE FIGURAS. ................................................................................................................................24
ndice de figuras.
FIGURA 3.1. ESQUEMA DE VARIABLES...........................................................................................................8 FIGURA 3.2. PUNTEROS NOTACIN. ...............................................................................................................9 FIGURA 3.3. VARIABLES INICIADAS.............................................................................................................12 FIGURA 3.4. VARIABLES LUEGO DE LA ASIGNACIN....................................................................................12 FIGURA 3.5. FRAME DE LA FUNCIN. ...........................................................................................................13 FIGURA 3.6. MSCARA DE REGISTROS.........................................................................................................14 FIGURA 3.7. FRAME CON REGISTROS SALVADOS Y LOCAL. ..........................................................................16 FIGURA 3.8. FRAME CON LOCALES. .............................................................................................................16 FIGURA 3.9 EQUIVALENCIAS ENTRE VARIABLES Y REGISTROS ....................................................................17 FIGURA 3.10. COMPILACIN DE CORRIMIENTOS Y OPERADORES AL BIT. .....................................................18 FIGURA 3.11. PALABRAS, MEDIAS PALABRAS, BYTES. .................................................................................22 FIGURA 3.12. ZONA DE MEDIAS PALABRAS..................................................................................................23 FIGURA 3.13. ZONA DE MEDIAS PALABRAS..................................................................................................23
30-08-2008