Ensamblador IA32: dividiendo la dirección en sus componentes.
Estoy teniendo problemas para dividir una dirección almacenada en sus componentes (es decir, en los bits de etiqueta, los bits de índice de conjunto y los bits de desplazamiento de bloque). Estoy tratando de implementar la siguiente función:
unsigned char check_cache(line cache[4], unsigned char addr);
Esta función comprobará si la caché dada almacena los datos en la dirección de memoria dada. Si la caché almacena los datos en la dirección de memoria dada (es decir, hay acierto en la caché), esta función devolverá los datos almacenados. De lo contrario (es decir, hay fallo en la caché), esta función devolverá 0xFF. Aquí está parte del código en C:
typedef struct {
char valid;
char tag;
char block[4];
} line;
unsigned char check_cache(line cache[4], unsigned char addr);
-Los conjuntos de la caché están asignados directamente (E=1), con un tamaño de bloque de 4 bytes (B=4) y cuatro conjuntos (S=4).
Necesito almacenar la dirección de memoria dada en un registro con un tamaño de byte y luego dividirla en tres componentes (bits de etiqueta, bits de índice de conjunto y bits de desplazamiento de bloque). Además, “es posible que desee usar operaciones a nivel de bits como andb y shrb e instrucciones de movimiento de 1 byte como movb para dividir la dirección”.
Aquí está mi código en ensamblador IA32 hasta ahora:
.global check_cache
check_cache:
pushl %ebp
movl %esp, %ebp
movl 12(%ebp), %eax
movl $0x3, %ebx
andl %eax, %ebx
shrl $0x2, %eax
movl $0x3, %ecx
andl %eax, %ecx
shrl $0x2, %eax
movl $0xF, %edx
andl %eax, %edx
popl %ebp
ret
No estoy seguro de dónde estoy fallando aquí, pero estoy obteniendo un error de segmentación. %eax debería almacenar toda la dirección, %ebx debería almacenar los bits de etiqueta, %ecx debería almacenar los bits de índice y %edx debería almacenar los bits de desplazamiento de bloque.
Se sugiere usar las operaciones a nivel de bits mencionadas anteriormente, ¿pero no es posible hacer esto sin usarlas?
Cualquier ayuda sería increíble. Gracias.
davy.ai
Parece que el fallo de segmentación podría ser causado por acceder a memoria a la que no se permite el acceso (es decir, intentando acceder a memoria de solo lectura). Puede intentar cambiar el código para cargar la dirección en un registro que se permita para almacenar datos (por ejemplo, %eax), y luego usar las operaciones a nivel de bit para extraer los bits de etiqueta, índice y desplazamiento.
Aquí está el código en ensamblador IA32 modificado que debería realizar la división requerida de la dirección:
Este código debería dividir correctamente la dirección en bits de desplazamiento, índice y etiqueta, utilizando las operaciones a nivel de bit como se sugiere. Tenga en cuenta que la máscara para los bits de desplazamiento es 0xFC, que extrae los dos bits menos significativos (los bits de desplazamiento de bloque) y establece los bits restantes en cero. La máscara para los bits de índice es 0x3, que extrae los dos bits inmediatamente después de los bits de desplazamiento. Se supone que los bits restantes son los bits de etiqueta, que se almacenan en %bl.