Intel x86-64

Anuncio
Arquitectura x86 de 32 bits
 Arquitectura de conjunto de instrucciones
Intel IA32

Conjunto de instrucciones x86-64


Sistemas Computacionales
Mario Medina C.
[email protected]
 Limitaciones de arquitectura de 32 bits


Arquitecturas de 64 bits
 DEC Alpha de 64 bits (1992)
 Sun SPARC de 64 bits (1995)
 Intel Itanium (2001)

Desarrollada en conjunto con HP
10M transistores
Usa VLIW (Very Long Instruction Word)
No es compatible con código IA32 existente

No tiene el desempeño esperado



Conocida como Intel x86 de 32 bits
Extiende arquitectura de 16 bits del 8086
Introducida en 1985 con Intel 80386
Espacio de direcciones virtual de 4 GiB
Tamaño máximo de archivo de 4 GiB
Arquitectura AMD x86-64
 AMD se adelanta a Intel en sacar una
arquitectura de 64 bits compatible con x86
Arquitectura de difícil implementación
El doble de IA32 en 2001
AMD y x86-64
 AMD introduce microprocesador de 64 bits
extendiendo x86 a 64 bits

AMD recluta diseñadores de DEC y otras compañías
 Arquitectura AMD x86-64





Compatible con Intel x86 de 32 bits
Nuevos formatos de datos
Mayor capacidad y desempeño
Microarquitectura AMD K8 (2003)
Líneas Opteron y Athlon 64 lideran el mercado
Intel y 64 bits
 En 2004, Intel introduce Itanium 2


 En 2006, Intel introduce Itanium 2 dual-core

1700M transistores!
No tiene buenos compiladores
No es compatible con código x86 existente
Pentium 4 lo supera en razón desempeño/costo
 En 2004, Intel integra arquitectura EMT64

©2014 Mario Medina C.
221M transistores
Mejora bastante el desempeño
Casi idéntico a AMD x86-64
1
Arquitectura AMD x86-64
 Punteros de 64 bits
 Enteros long int de 64 bits
 Operaciones enteras de 8, 16, 32 y 64 bits
 16 registros de propósito general
 Paso de argumentos via registros en vez de pila
 Operaciones condicionales
 Nuevas instrucciones para operaciones de
punto flotante
Tipos de datos x86-64
 Sufijos y largos










char (b): 1 byte
short (w): 2 bytes
int (l): 4 bytes
unsigned int (l): 4 bytes
long int (q): 8 bytes
unsigned long (q): 8 bytes
char * (q): 8 bytes
float (s): 4 bytes
double (d): 8 bytes
long double (s): 16 bytes
Tipos de datos x86-64
 Punteros de 8 bytes (64 bits) permiten
direccionar 264 bytes (16 exabytes) de
memoria

Procesadores Intel y AMD actuales sólo
direccionan 248 (256 terabytes) de RAM física
 Datos long double usan 16 bytes para
almacenar números de punto flotante en
formato de 80 bits ya visto

Sólo son usados 10 bytes menos significativos
Registros x86-64
 16 registros de 64 bits

%rax, %rbx, %rcx, %rdx, %rdi, %rsi, %rsp,
%rbp, %r8 a %r15
 Acceso directo a 32 bits menos significativos
 Acceso directo a16 bits menos significativos
 Acceso directo a 8 bits menos significativos
 Registro %rsp es puntero a la pila
 No hay puntero base!
16 Registros x86-64
63
31
8 7
15
0
%rax
%eax
%ax
%ah
%al
%rbx
%ebx
%bx
%bh
%bl
%rcx
%ecx
%cx
%ch
%cl
%rdx
%edx
%dx
%dh
%rsi
%esi
%si
%sil
%rdi
%edi
%di
%dil
%rbp
%ebp
%bp
%bpl
%rsp
%esp
%sp
%spl
%r8
%r8d
%r8w
%r8b
%r15
%r15d
%r15w
%r15b
%dl
Ejemplo x86-32 y x86-64
 Sea la función simple() en C
long int simple(long int *xp, long int y) {
long int t = *xp + y;
*xp = t;
return t;
}
 Compilando para x86 de 32 bits
gcc –m32 simple.c
 Compilando para x86 de 64 bits
gcc –m64 simple.c
©2014 Mario Medina C.
2
Código x86-32
 Compilando como
Código x86-64
 Compilando como
gcc –S –m32 simple.c
simple:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx
movl (%edx), %eax
addl 12(%ebp), %eax
movl %eax, (%edx)
leave
ret
gcc –S –m64 simple.c
simple:
addq (%rdi), %rsi
movq %rsi, %rax
movq %rsi, (%rdi)
ret
 Código x86-64 tiene 4 instrucciones y 2
accesos a memoria vs. 8 instrucciones y 7
accesos a memoria para x86
Direccionamiento relativo al PC
 Contador de programa (instruction pointer)
de 64 bits llamado %rip
 Direccionamiento inmediato suma una
constante de 32 bits al contador de programa
 Acceso rápido a datos a ±231 de %rip
add 0x234567(%rip), %rax
 Suma M[%rip + 0x234567] al registro
%rax
Nuevas versiones de mov
 movq S, D

Mueve operando de 64 bits de S a D
Operandos inmediatos limitados a 32 bits con extensión
de signo
 movsbq S, D

Mueve byte a quad word con extensión de signo
 movswq S, D

Mueve word a quad word con extensión de signo
 movslq S, D

Mueve double word a quad word con extensión de
signo
Nuevas versiones de mov
 movzbq S, D

Mueve byte a quad word con extensión cero
 movzwq S, D

Mueve word a quad word con extensión cero
 No existe instrucción movzlq

Mover 32 bits a registro de 64 bits
automáticamente limpia los 32 bits superiores
 movabsq I, R

Nuevas versiones de pushl y popl
 pushq S



Similar a pushl, pero para 64 bits
R[%rsp]  R[%rsp] – 8
M[R[%rsp]]  S
 popq D



Similar a popl, pero para 64 bits
D  M[R[%rsp]]
R[%rsp]  R[%rsp] + 8
Mueve valor inmediato de 64 bits a un registro
©2014 Mario Medina C.
3
Operaciones aritméticas de 64 bits
 Operaciones normales extendidas a 64 bits
usando sufijo q

Ejemplo de operaciones de 64 bits
 Código c
long int func1(int x, int y) {
long int t1 = (long) x + y;
long int t2 = (long) (x + y);
return t1 | t2;
}
addq, leaq, incq, salq, decq, etc.
 Instrucciones que generan resultados de 32
bits (addl) hacen 0 los 32 bits superiores
 Instrucciones que generan resultados de 8 ó
16 bits (addw) no modifican los otros bits
 Cast tiene precedencia sobre suma

Primera suma es de 64 bits, segunda es de 32 bits
Ejemplo de operaciones de 64 bits
 Código x86-64
# suponemos x esta en %edi, y en %esi
func1:
movslq %edi, %rdi
# conv. x a long
movslq %esi, %rsi
# conv. y a long
addq %rdi, %rsi
# suma en 64 bits
leal (%esi, %edi), %eax # suma x+y en 32 bits
cltq
# extiende %eax
# a 64 bits
orq %rsi, %rax
# OR de 64 bits
ret
Operaciones aritméticas de 64 bits
Instrucción Efecto
Descripción
imulq S
R[%rdx]:R[%rax]SR[%rax]
Multiplica con signo
mulq S
R[%rdx]:R[%rax]SR[%rax]
Multiplica sin signo
cltq
R[%rax]
SignExtend(R[%eax])
Convierte %eax a
quad word
cqto
R[%rdx]:R[rax]
SignExtend(R[%rax])
Convierte %rax a
oct word
idivq S
R[%rdx]R[%rdx]:R[%rax] mod S
División con signo
R[%rax]R[%rdx]:R[%rax]S;
divq S
R[%rdx]R[%rdx]:R[%rax] mod S
División sin signo
R[%rax]R[%rdx]:R[%rax]S;
Llamadas a funciones
 Instrucción callq almacena dirección de
retorno de 64 bits en la pila
 Arquitectura x86-64 usa los registros para
pasar hasta 6 argumentos en vez de la pila

Reduce tráfico de datos desde y hacia memoria
 No es necesario crear marco de activación

Sólo para almacenar variables locales
 No se usa un registro como puntero al marco
de activación

Paso de parámetros
Número del argumento
Operando
(bits)
1
2
3
4
5
6
64 %rdi %rsi %rdx %rcx %r8
%r9
32 %edi %esi %edx %ecx %r8d %r9d
16 %di
%si
%dx
%cx
%r8w %r9w
8 %dil %sil %dl
%cl
%r8b %r9b
Todo es relativo al registro %rsp
©2014 Mario Medina C.
4
Ejemplo
 Código C
Ejemplo
 Código x86-64
void func2(long a1, long *a1p, int a2, int
*a2p, short a3, short *a3p, char a4,
char *a4p) {
*a1p += a1;
*a2p += a2;
*a3p += a3;
*a4p += a4;
}
func2:
movq 16(%rsp), %r10
addq %rdi, (%rsi)
addl %edx, (%rcx)
addw %r8w, (%r9)
movzbl 8(%rsp), %eax
addb %al, (%r10)
ret
Convención de paso de parámetros
 Registros %rdi, %rsi, %rdx, %rcx, %r8 y
%r9 son usados para pasar parámetros
 Registro %rax es el valor retornado por la
función
 Registro %rsp es el puntero a la pila
 Registros %rbx, %rbp, %r12 a %r15 son
Callee-Save
 Registros %r10 y %r11 son Caller-save
#
#
#
#
#
#
#
#
a1 esta en %rdi
a1p esta en %rsi
a2 esta en %edx
a2p esta en %rcx
a3 esta en %r8w
a3p esta en %r9
a4 esta en %rsp+8
a4p esta en %rsp+16
Marcos de activación en x86-64
 Necesarios si





Función usa demasiadas variables locales
Algunas variables locales son vectores o estructuras
Función calcula la dirección de alguna variable local
usando operador de dirección &
Función debe pasar args. via la pila a otra función
Función necesita salvar algún registro callee-save
 Marco de función es de tamaño fijo
 Accesos son relativos a registro %rsp
Movimiento condicional
Movimiento condicional
 Instrucciones de movimiento condicional transfieren
datos si se cumple una condición
Instrucción
Sinónimo Condición
cmove S, R
cmovz
ZF
Igual / Cero
Si la condición no se cumple, no hay movimiento de datos
Instrucciones de movimiento condicional reemplazan 2
instrucciones
cmovne S, R
cmovnz
~ZF
Distinto / No cero


 Formato CMOVXX donde XX es una condición

Condiciones posibles son similares a instrucciones setXX y
saltos condicionales jXX
 Introducidas por Intel en Pentium Pro en IA32
 Aprovechadas al máximo por AMD en AMD64
©2014 Mario Medina C.
Descripción
cmovs S, R
SF
Negativo
cmovns S, R
~SF
No negativo
cmovg S, R
cmovnle
cmovge S, R
cmovnl
~(SF^OF)&~ZF Mayor (signed >)
~(SF^OF)
Mayor o igual (signed >=)
cmovl S, R
cmovnge
SF^OF
Menor (signed <)
cmovle S, R
cmovng
(SF^OF)|ZF
Menor o igual (signed <=)
cmova D
cmovnbe
~CF &~ZF
Superior (unsigned >)
cmovae D
cmovnb
~CF
Superior o igual (unsigned >=)
cmovb D
cmovnae
CF
Inferior (unsigned <)
cmovbe D
cmovna
CF|ZF
Inferior o igual (unsigned <=)
5
Ejemplo de movimiento condicional
 Código C condicional
 Código x86 de 32 bits usando instrucción de
movimiento condicional
if (a == 5) x = y
 Suponga que %eax contiene a, %ebx
contiene x y %ecx contiene y
 Código x86 de 32 bits es
cmpl $5, %eax
jnz Fin
#
#
#
#
movl %ecx, %ebx
Fin:
Ejemplo de movimiento condicional
Compara a con 5
Si no es igual,
ir a Fin
Copia y en x
cmpl $5, %eax
# Compara a con 5
cmovz %ecx, %ebx # Copia y en x
 Instrucciones de movimiento condicional



Ejemplo de movimiento condicional
 Sea el siguiente código C
v = (expr_test) ? expr_V : expr_F;
 Generalmente esto se compila como
if (!expr_test)
goto falso;
v = expr_V;
goto fin;
Falso:
v = expr_F;
Fin:
Permiten reducir la longitud del código
Permiten evitar penalidades de predicción de salto
causadas por saltos condicionales
Acelera la ejecución de programas en
procesadores que tienen pipelining
Ejemplo de movimiento condicional
 Usando movimiento condicional, el código
generado es similar a éste
vt = expr_V;
v = expr_F;
t = expr_test;
if (t) v = vt;
 Este último condicional se realiza en una sola
sola instrucción de movimiento condicional

vt se copia a v sólo si t es verdadera
Movimiento condicional
 La gran ventaja de las instrucciones de
movimiento condicional es que reducen el
número de saltos



Reduce la penalidad en procesadores segmentados
En el primer caso, hay 2 saltos
En el segundo caso, no hay saltos
 No es aplicable a casos en que evaluar las
expresiones tengan efectos secundarios
x = (xp) ? *xp : 0;
©2014 Mario Medina C.
6
Descargar