Arquitectura x86-64
Arquitectura x86-64
Registros Usados
| Registro | Uso |
|---|---|
%rax |
Retornos, división (cociente) |
%rdi |
1º parámetro |
%rsi |
2º parámetro |
%rdx |
3º parámetro, módulo (resto) |
%rcx |
4º parámetro |
%r8 |
5º parámetro |
%r9 |
6º parámetro |
%rbp |
Base pointer (frame pointer) |
%rsp |
Stack pointer |
%r10 |
Temporal 1 (operaciones) |
%r11 |
Temporal 2 (operaciones) |
Convención de Llamada
Parámetros (primeros 6):
%rdi, %rsi, %rdx, %rcx, %r8, %r9
Retorno: %rax
Limitación: Solo soportamos hasta 6 parámetros.
Stack Frame
Alta dirección
+-----------------+
| Dir. retorno |
+-----------------+
%rbp -> | %rbp anterior |
+-----------------+
-8 | Variable 1 | ← Primera variable/temporal
-16 | Variable 2 |
-24 | Variable 3 |
...
%rsp -> | Espacio libre |
Baja dirección
Prólogo:
enter $(8 * N), $0 # push rbp, mov rsp rbp, sub
Epílogo:
leave # mov rbp rsp, pop rbp
ret
Instrucciones Principales
Movimiento:
mov $5, %r10 # Constante a registro
mov -8(%rbp), %r10 # Desde stack a registro
mov %r10, -8(%rbp) # De registro a stack
Aritmética:
add %r11, %r10 # r10 = r10 + r11
sub %r11, %r10 # r10 = r10 - r11
imul %r11, %r10 # r10 = r10 * r11
neg %r10 # r10 = -r10
División y Módulo:
mov dividendo, %rax
cqo # Extender signo de rax a rdx:rax
idiv divisor # rax = cociente, rdx = resto
Comparaciones (menor que):
cmp %r11, %r10 # Comparar r10 con r11
mov $0, %r11 # Asumir falso
mov $1, %r10 # Valor verdadero
cmovl %r10, %r11 # if r10 < r11: r11 = 1
Comparaciones (mayor que):
cmp %r11, %r10 # Comparar r10 con r11
mov $0, %r11 # Asumir falso
mov $1, %r10 # Valor verdadero
cmovg %r10, %r11 # if r10 > r11: r11 = 1
Comparaciones (igual):
cmp %r10, %r11 # Comparar r11 con r10
mov $0, %r11 # Asumir falso
mov $1, %r10 # Valor verdadero
cmove %r10, %r11 # if r10 == r11: r11 = 1
Operaciones Lógicas:
and %r11, %r10 # AND bit a bit
or %r11, %r10 # OR bit a bit
test %r10, %r10 # Test para NOT
sete %r10b # Set if equal (para NOT)
Saltos Condicionales:
cmp %r10, %r11 # Comparar
jne .L0 # Saltar si no igual (usado en if !cond)
Saltos Incondicionales:
jmp .L0 # Salto incondicional
Llamadas a Funciones:
mov $0, %rax # Limpiar rax (para variádicas)
call función # Llamar función
ret # Retornar
Ejemplo
Código: integer suma(integer a, integer b) { return a + b; }
TAC:
┌─ func suma
t0 = a + b
return t0
└─ endfunc suma
Assembly:
suma:
enter $(8 * 3), $0 # 3 variables (a, b, t0)
mov %rdi, -8(%rbp) # Guardar parámetro a
mov %rsi, -16(%rbp) # Guardar parámetro b
mov -8(%rbp), %r10 # Cargar a en r10
mov -16(%rbp), %r11 # Cargar b en r11
add %r11, %r10 # r10 = a + b
mov %r10, -24(%rbp) # Guardar resultado en t0
mov -24(%rbp), %rax # Cargar t0 en rax (retorno)
leave
ret
Referencias
Guía: x86-64-architecture-guide.pdf