Procesadores Intel x86 Familia de microprocesadores desarrollados por Intel que son la base de los PCs Arquitectura Intel x86 Sistemas Computacionales Mario Medina C. [email protected] Procesadores de la familia x86 Leer instrucción de memoria y colocarla en la CPU (Fetch) Decodificar la instrucción (Decode) y actualizar el contador de programa Ejecutar la instrucción (Execute), devolviendo los resultados a los registros o a memoria tienen conjunto básico común de registros tienen conjunto básico común de instrucciones mantienen la arquitectura del conjunto de instrucciones (Instruction Set Architecture) Estructura de una CPU 8088 Operación básica de un 8088 Tres pasos básicos: Intel 8088 (1980) a Intel i7 (2014) EU ejecuta las instrucciones BIU realiza operaciones de bus bajo control de la EU Lee instrucciones y operandos, escribe resultados Dos unidades internas Unidad de ejecución (Execution Unit) Unidad de interfaz de bus (Bus Interface Unit) Estructura de una CPU 8088 Estructura de una CPU 8088 EU y BIU operan en paralelo Mientras EU procesa una instrucción, la BIU está leyendo las instrucciones siguientes Almacenadas en una cola de instrucciones de 4 bytes Segmentación del trabajo (pipelining) Minimiza tiempos de inactividad Aumenta instrucciones procesadas por unidad de tiempo Desacopla la EU del acceso a memoria (C) 2014 Mario Medina C. 1 Bus Interface Unit (BIU) Realiza los accesos a memoria Implementa el modelo de memoria Contiene Memoria segmentada de 8088 Intel 8088 direcciona memoria física de 1 MiB genera direcciones físicas de 20 bits usando 2 registros de 16 bits Los registros de segmento CS, DS, SS y ES Puntero a instrucción IP Bloque de suma de direcciones ∑ Cola de instrucciones de 4 bytes Buses de datos internos de 16 bits Segmentos Decodifica las instrucciones leídas por la BIU Ejecuta las instrucciones Contiene Segmento: bloque de memoria de 64 KiB 8088 puede direccionar 4 segmentos en un instante dado Unidad Aritmético-Lógica (ALU) 4 registros de datos 4 registros punteros e índices Operandos de 8 ó 16 bits Estos segmentos pueden ser disjuntos, traslapados o iguales Execution Unit (EU) Accesibles como registros de 8 ó 16 bits CS: Code segment DS: Data segment SS: Stack segment ES: Extra segment Usados en operaciones de transferencias de datos Usados con registros de segmentos Registros 8088 (C) 2014 Mario Medina C. 9 flags o bits de estado y de control Bits de condición 8088 2 Registros 80386 y posteriores Tipos de datos Intel x86 Palabras (words): 16 bits Registros de propósito general extendidos a 32 bits 2 registros de segmento extras Cola de instrucciones de 6 instrucciones Más flags de condición Herencia del 8086 Palabras dobles (doublewords): 32 bits Palabras cuádruples (quadwords): 64 bits Instrucción mov: movimiento de datos movb (move byte) movw (move word) movl (move doubleword) Punteros: 32 bits Registros de 32 bits Intel x86 Registros enteros Almacenan datos y direcciones 8 registros de 32 bits Registro %eax Accesibles como 8 registros de 16 bits Registro %ax %ax %ah %al %ebx %bx %bh %bl %ecx %cx %ch %cl %edx %dx %dh %dl %esi %si %edi %di %esp %sp %ebp %bp Ejemplo: addl S, D Registros %ah y %al Formato ensamblador GNU Assembler (GAS) Partes de una instrucción Operación: qué hacer (addl) Operandos fuente (S) y destino (D) Suma S + D y almacena resultado en D Los 4 primeros son accesibles como bytes %eax Instrucciones Qué son S y D? Datos en registros Constantes Datos en memoria Modos de Direccionamiento Modo Inmediato Usado para definir constantes Formato: $Imm Valor: Imm Modo Registro Especifica el registro de 8, 16 ó 32 bits a usar Formato: Ea Valor: R[Ea] Modos de Direccionamiento Modos de direccionamiento a memoria Modo Absoluto Especifica una dirección absoluta de memoria Formato: Imm Valor: M[Imm] Modo Indirecto (C) 2014 Mario Medina C. Indican cómo calcular la dirección efectiva del operando Dirección dada por el contenido de un registro Formato: (Ea) Valor: M[R[Ea]] 3 Modos de Direccionamiento Modo Indexado + Constante Modo Base + Desplazamiento Modos de Direccionamiento Útil para acceso a vectores Formato: Imm(Eb) Valor: M[Imm + R[Eb]] Modo Indexado escalado Modo Indexado Formato: Imm(Eb, Ei) Valor: M[Imm + R[Eb] + R[Ei]] Dirección se calcula como registro base + índice Formato: (Eb, Ei) Valor: M[R[Eb] + R[Ei]] s: factor de escala 1, 2, 4 ó 8 Formato: (, Ei, s) Valor: M[R[Ei]*s] Modo Indexado escalado + Constante Formato: Imm(, Ei, s) Valor: M[Imm + R[Ei]*s] Modos de Direccionamiento Modo Indexado escalado Tipo Formato: (Eb, Ei, s) Valor: M[R[Eb] + R[Ei]*s] Modo Indexado escalado + Constante Resumen Modos Modo más complejo Formato: Imm(Eb, Ei, s) Valor: M[Imm + R[Eb] + R[Ei]*s] Formato Evalúe la dirección efectiva Dirección 0x100 0x104 0x108 0x10C Valor 0xFF 0xAB 0x13 0x11 Registro %eax %ecx %edx Valor 0x100 0x1 0x3 (C) 2014 Mario Medina C. %eax 0x104 $0x108 (%eax) 4(%eax) 9(%eax, %edx) 260(%ecx, %edx) 0xFC(,%ecx, 4) (%eax, %ecx, 4) 2(%eax, %ecx, 2) Nombre Imm Inmediato Registro Ea R[Ea] Registro Memoria Imm M[Imm] Absoluto Memoria (Ea) M[R[Ea]] Indirecto Memoria Imm(Eb) M[Imm +R[Eb]] Base + Desp. Memoria (Eb, Ei) M[R[Eb] +R[Ei]] Indexado Memoria Imm(Eb, Ei) M[Imm +R[Eb] +R[Ei]] Indexado + Constante Memoria (, Ei, s) M[R[Ei]*s] Indexado escalado Memoria Imm(, Ei, s) M[Imm +R[Ei]*s] Indexado escalado + C. Memoria (Eb, Ei, s) M[R[Eb] +R[Ei]*s] Indexado escalado Memoria Imm(Eb, Ei, s) M[Imm+R[Eb]+R[Ei]*s] Indexado escalado + C. Ejemplo Datos Valor operando Inmediato $Imm Movimiento de datos Operando fuente S puede ser Inmediato Registro Memoria Operando destino D puede ser Registro Memoria No se pueden mover datos entre 2 posiciones de memoria Datos se leen desde memoria a registro Datos se escriben desde registro a memoria 4 Movimiento de datos movl S, D Mueve doubleword (32 bits) D S movw S, D Instrucciones anteriores mueven datos de un largo dado por el sufijo desde un operando fuente S a un operando destino D Mueve word (16 bits) D S Tanto fuente como destino tienen que tener el mismo largo Pero, cómo copiar datos desde un registro de 8 bits a 32 bits, por ejemplo? movb S, D Movimiento de datos Mueve byte (8 bits) D S Instrucciones no modifican otros bits Instrucciones movsbl y movzbl Cuál es el signo del operando destino? Depende del tipo del dato original Movimiento de datos movsbl S, D Mueve byte extendido en signo Move sign-extended byte to long Copia bit 7 en bits 31-8 D SignExtend(S) movzbl S, D Mueve byte extendido a cero Move zero-extended byte to long Bits 31-8 son 0 D ZeroExtend(S) Operaciones aritmético-lógicas Instrucción Efecto Descripción leal S, D D &S Carga dirección incl D DD+1 Incrementa D decl D DD-1 Decrementa D negl D D -D Niega D notl D D ~D Complementa D addl S, D DD+S Suma S y D subl S, D DD-S Resta S a D imull S, D DD*S Multiplica S y D xorl S, D DD^S XOR S y D orl S, D DD|S OR S y D andl S, D DD&S AND S y D Instrucción leal S, D Variante de movl Calcula la dirección en memoria de S (&S) Almacena la dirección calculada en D Usada para generar punteros y cálculos aritméticos Ejemplo de puntero Ejemplos de leal Suponga que %eax contiene x, y %ecx contiene y. Qué calculan: 1. 2. 3. movl 10(%ecx), %eax %eax M[%ecx + 10] 4. leal 10(%ecx), %eax 5. %eax %ecx + 10 Ejemplo: %edx contiene variable x 6. leal leal leal leal leal leal 6(%eax), %edx (%eax, %ecx), %edx (%eax, %ecx, 4), %edx 7(%eax, %eax, 8), %edx 0xa(, %ecx, 4), %edx 9(%eax, %ecx, 2), %edx Qué hace leal 7(%edx, %edx, 4), %eax? %eax almacena 5x+7 (C) 2014 Mario Medina C. 5 Operaciones aritméticas Dados Evalúe Dirección 0x100 0x104 0x108 0x10C Valor 0xFF 0xAB 0x13 0x11 1. Registro %eax %ecx %edx Valor 0x100 0x1 0x3 6. 2. 3. 4. 5. addl %ecx, (%eax) subl %edx, 4(%eax) imull $16, (%eax, %edx, 4) incl 8(%eax) decl %ecx subl %edx, %eax Operaciones de desplazamiento Instrucción Efecto Descripción sall k, D D D << k Desp. izquierda shll k, D D D << k Desp. izquierda sarl k, D D D >> k Desp. derecha aritmético shrl k, D D D >> k Desp. derecha lógico Desplazamientos Desplazamiento va de 0 a 31 Generalmente operando inmediato o %cl Operaciones sall y shll son iguales Operaciones sarl y shrl son diferentes sarl hace desplazamiento aritmético a la derecha shrl hace desplazamiento lógico a la derecha Ejemplo: código C int arith(int x, int y, int z){ int t1 = x + y; int t2 = z*48; int t3 = t1&0xFFFF; int t4 = t2*t3; Extensión de signo mantiene el signo del resultado return t4; } Rellena con 0s Ejemplo: código ensamblador Suponga que x, y y z están a 8, 12 y 16 bytes de (%ebp), respectivamente movl 12(%ebp), %eax // movl 16(%ebp), %edx // addl 8(%ebp), %eax // leal (%edx, %edx, 2), %edx sall $4, %edx // andl $65535, %eax // imull %eax, %edx // movl %edx, %eax // Lee y Lee z Calcula t1 Calcula Calcula Calcula Retorna t2 t3 t4 t4 Multiplicación de enteros imull S, D: Multiplica 2 operandos Cada operando tiene 32 bits Resultado truncado a 32 bits imull S: Multiplicación de 1 operando Operando S tiene 32 bits Resultado tiene 64 bits Se multiplica con contenido de %eax 32 bits más significativos en %edx 32 bits menos significativos en %eax mull S: multiplica enteros sin signo (C) 2014 Mario Medina C. 6 División idivl realiza división de 64 bits con signo Dividendo: concatenación de %edx:%eax Divisor: operando de la instrucción Cuociente de la división queda en %eax Resto de la división queda en %edx Ejemplos Suponga x en 8(%ebp) e Suponga x en 8(%ebp) y en 12(%ebp) e y en 12(%ebp) Multiplica x e y, retorna Divide x por y, retorna resultados en la pila resultados en la pila movl 8(%ebp), %eax imull 12(%ebp) pushl %edx pushl %eax divl realiza división de 64 bits sin signo cltd convierte contenido de %eax a 64 bits con signo movl 8(%ebp), %eax cltd idivl 12(%ebp) pushl %eax pushl %edx Extiende signo de %eax en %edx Operaciones aritméticas Instrucción Efecto Descripción imull S R[%edx]:R[%eax]SR[%eax] Multiplica con signo mull S R[%edx]:R[%eax]SR[%eax] Multiplica sin signo cltd R[%edx]:R[%eax] SignExtend(R[%eax]) Convierte a quad word idivl S R[%edx]R[%edx]:R[%eax] mod S División con signo Bits de condición CPUs Intel mantienen flags o bits de condición R[%eax]R[%edx]:R[%eax]S divl S R[%edx]R[%edx]:R[%eax] mod S División sin signo Describen resultados de últimas operaciones de ALU Carry Flag (CF): Última operación generó un rebalse Zero Flag (ZF): Última operación generó un cero Sign Flag (SF): Última operación generó un número negativo Overflow Flag (OF): ÚItima operación generó un rebalse de complemento a 2 R[%eax]R[%edx]:R[%eax]S Ejemplo: resta Calcular 0xE4534980 – 0x94533443 Equivalente a 0xE4534980+[0x94533443]2 Restar B es sumar el complemento a 2 de B Equivalente a 0xE4534980+0x6BACCBBD Resultado es 0x15000153D Cómo quedan los bits de condición? ZF = 0 CF = 1 SF = 0 OF = 1 (C) 2014 Mario Medina C. Ejemplo: t = a + b Implementado con instrucción addl CF: (unsigned t) < (unsigned a) ZF: (t == 0) SF: (t < 0) OF: (a < 0 == b < 0) && (t < 0 != a < 0) Instrucción leal no modifica bits de condición Operaciones lógicas hacen CF y OF igual a 0 Desplazamientos hacen OF 0 Desplazamientos a la izquierda modifican CF 7 Instr. Comparación y test •Modifican los códigos de condición •No modifican operandos Instrucción Basado en Descripción cmpb S2, S1 S1 - S 2 Compara bytes testb S2, S1 S1 & S 2 Test bytes cmpw S2, S1 S1 - S 2 Compara palabras testw S2, S1 S1 & S 2 Test palabras cmpl S2, S1 S1 - S 2 Compara palabras dobles testl S2, S1 S1 & S 2 Test palabras dobles Instr. Comparación y test Instrucción de comparación no modifica sus argumentos subl %eax, %ecx Instrucción hace %ecx %ecx - %eax y modifica los códigos de condición cmpl %eax, %ecx Instrucción no modifica %ecx, sólo calcula %ecx %eax y modifica los códigos de condición andl %eax, %ecx modifica %ecx testl %eax, %ecx no modifica %ecx Acceso a códigos de condición Instrucción Sinónimo Condición sete D setz setne D setnz ZF sets D setns D Descripción Igual / Cero ~ZF Distinto / No cero SF Negativo ~SF No negativo setg D setnle ~(SF^OF)&~ZF Mayor (signed >) setge D setnl ~(SF^OF) Mayor o igual (signed >=) setl D setnge SF^OF Menor (signed <) setle D setng (SF^OF)|ZF Menor o igual (signed <=) seta D setnbe ~CF &~ZF Superior (unsigned >) setae D setnb ~CF Superior o igual (unsigned >=) setb D setnae CF Inferior (unsigned <) setbe D setna CF|ZF Inferior o igual (unsigned <=) Instrucciones setX Resultado de instrucciones setX es 1 byte de valor 0 ó 1 Destino de instrucción es un registro de 8 bits ó un byte en memoria Usar movzbl para convertir resultado a 32 bits Ejemplo: si a está en %eax y b en %edx cmpl %eax, %edx setl %al movzbl %al, %eax Instrucciones de salto •Cambio en secuencia de ejecución de instrucciones •Saltos condicionales e incondicionales Instrucción Sinónimo Condición Descripción jmp Rótulo 1 jmp *Operando Salto directo 1 Salto indirecto je Rótulo jz ZF Cero jne Rótulo jnz ~ZF No cero js Rótulo SF Negativo jns Rótulo ~SF No negativo (C) 2014 Mario Medina C. a < b? Bits 0-7 %eax son 0 ó 1 Extiende valor a 32 bits Ahora %eax es 0 ó 1 Instrucciones de salto Instrucción Sinónimo Condición Descripción jg Rótulo jnle ~(SF^OF)&~ZF Mayor (signed) jge Rótulo jnl ~(SF^OF) Mayor o igual jl Rótulo jnge SF^OF Menor jle Rótulo jng (SF^OF)|ZF Menor o igual ja Rótulo jnbe ~CF &~ZF Superior (unsigned) jae Rótulo jnb ~CF Superior o igual jb Rótulo jnae CF Inferior jbe Rótulo jna CF|ZF Inferior o igual Rótulo es una referencia a una línea en el código fuente 8 Ejemplo Lazo: testl %eax, %ecx jz Fin subl %edx, %esi ja Lazo Fin: pop %edx Código anterior salta a Fin si %eax es igual a %ecx. En caso contrario, resta %edx de %esi, y salta a Lazo si %esi es mayor que %edx Manejo de la pila Instrucciones de manejo de pila pushl S Almacena S en la pila R[%esp] R[%esp]-4 M[R[%esp]] S popl D Retira D de la pila D M[R[%esp]] R[%esp] R[%esp]+4 Pila del procesador Pila y registro “Stack Pointer” Área de memoria utilizada para almacenar y recuperar rápidamente datos Inicialmente Vital para manejo de funciones Acceso via instrucciones especiales popl y pushl Indexada por registro dedicado %esp Crece hacia direcciones bajas de memoria Direcciones de Memoria %eax %edx 0x123 0 %esp 0x108 pushl %eax %eax %edx %esp Comienzo de pila • • • • • • • • • 0x108 0x104 0x108 0x123 Tope de pila Ejemplo: exchange() Código intercambia dato apuntado por xp y dato contenido por y Código utiliza variable intermedia local x Ejemplo pasa argumentos a función via la pila (C) 2014 Mario Medina C. 0x123 0x123 0x108 Comienzo de pila Tope de pila int exchange(int *xp, int y){ int x = *xp; *xp = y; return x; } %eax %edx %esp Comienzo de pila 0x108 Código C popl %edx 0x123 0 0x104 0x123 Tope de pila Ejemplo: exchange() Código Assembly movl movl movl movl movl 8(%ebp), %eax 12(%ebp), %edx (%eax), %ecx %edx, (%eax) %ecx, %eax Parámetros de funciones se pasan a través de memoria, indexados por el puntero base (base pointer) %ebp Convención: parámetros xp e y de la función están a 8 y 12 bytes de (%ebp), respectivamente Convención: funciones retornan resultados en %eax 9 Comentarios Hemos visto 30 instrucciones Intel 80386 tiene 134 instrucciones No todas las instrucciones aceptan el prefijo b Las siguientes instrucciones no existen Instrucción imulb S, D no está permitida movlsbb, movzbb, pushb, popb, leab Debería multiplicar bytes almacenados en S y D y almacena resultado en D En cambio, la instrucción imulb S si lo está Multiplica el byte almacenado en S por %al y almacena resultado de 16 bits en %ax (C) 2014 Mario Medina C. 10