Assembly x86: CISC, Little Endian

.file	"t.c"
	Archivo de origen
.text
	Programa
.globl nombre
	Nombre global
.local nombre
	Nombre local a la unidad de compilacin
.type	nombre, @function
	Nombre es funcin
.size	label, .-label
	Tamao de la funcin que comienza en <label> y termina aqu

.long l
.half s
.byte b
.asciz "hola"
.align 4
	Alinea rtulo contiguo
.skip n
	Lo que falta por alinear

Registros:
%e[a-d]x
	De uso general: A = Acumulador, C = Contador
%e[sd]i
	Registros ndices

%ebp
	Base Pointer -> Direcciones superiores a inferiores
%esp
	Stack Pointer -> Direcciones superiores a inferiores. %esp <= %ebp
%eip
	Instruction Pointer
		- Direccin instruccin en ejecucin
		- Autoincrementa

%eflags
	Flags de informacin:
		Carry?
		Cero?

Formato Instruccin:
	<op> <v>, <d> <==> <d> <- <v>, <op>, <d>
	<v> o <d> pueden estar en memoria RAM, pero no ambos al mismo tiempo.

Datos en Memoria:
	struct {short x; short y;} puntos[100];
	puntos[i].y <==>
		2(%ebx, %esi, 4)
		<tamao short>(<direccin "puntos">, <ndice>, sizeof(struct))

	Ej:
		-4(%ebp)  <==>  M[%ebp + x + (-4)]
		-400(%edx, %esi, 8)  <==>  M[%edx + %esi * 8 + (-400)]
		<registrp> + <registro> * {1 | 2 | 4 | 8} + <offset {0 | 8 | 16 | 32}>

Aritmtica:
	movl (32b), movw (16b), movb (8b),
	addl, addw, addb, adcl (carry), adcw, adcb,
	subl, subw, subb, sbbl (burrow),
	negl (cambio signo: -x == negl x),
	mull, divl (unsigned), imull, idivl (signed),
	andl, orl.
	Shift:
		s (shift) .
		{a (aritmtico/signed) | l (lgico/unsigned)} .
		{l (left) | r (right)} .
		{l (32b) | w (16b) | b (8b)}

Valores Inmediatos: $n (constantes)

Comparacin: cmp <v1>, <v2> <==> %eflags <- <v1> - <v2>

Salto Incondicional:
	jmp <etiqueta>
Saltos Condicionales: j . {condicin} <etiqueta>
Condiciones:
	Igualdad:
		e  ==
		ne !=
	Desigualdad:
		Signed:
			g  >
			ge >=
			l  <
			le <=
		Unsigned:
			a  >
			ae >=
			b  <
			be <=

Cast: (OJO: Rellenar destino con 0) (Notacin: _ = epsilon)
	mov .
	{s (signed) | _ (unsigned)} .
	{l | w | b} .									/* Cuntos bits tomar: 32, 16, 8*/
	{l | w | b}										/* Tamao registro origen*/
	%{e[a-d] | [a-d], [a-d]l}x		/* Registro origen */
	%e[a-d]x											/* Registro destino */

  Ejemplos:
  movswl %eax /*16b*/, %ebx /*32b*/
  movsbl %eax /*16*/, %ebx /*32*/
  movw %eax /*32*/, %bx /*16*/
	movl %eax /*32*/, %bl /*8*/
	movw %ax /*16*/, %ebx

Layout Marco Activacin:

        [Direccin Retorno (%eip siguiente al call)
%ebp -> [%ebp Marco Activacin Anterior
        [Respaldo %e[a-d]x del Llamador
%esp -> [Variables Locales del Llamado

Manejo Stack: Crece hacia abajo.
	Apilar: push . {l | w | b} <valor> <==>
		{%esp -= bytes(l|w|b); mov . {l | w | b} <valor>, (%esp);}
	Desapilar: pop . {l | w | b} <registro> <==>
		{mov . {l | w | b} (%esp), <registro>; %esp += bytes(l|w|b);}

	Nota: %esp apunta al tope del stack, inclusive.

Protocolo Invocacin Procedimientos:
	Al entrar (funcin invocada):
		pushl %ebp
		movl %esp, %ebp
		push . {l | w | b} <registros a usar>
		sub . {l | w | b} $<tamao variables locales>, %esp
	Al retornar: El valor retornado queda en %eax
		add . {l | w | b} $<tamao variables locales>, %esp
		pop . {l | w | b} <registros resguardados>
		popl %ebp
		ret

El llamador debe dejar los parmetros apilados en orden inverso (partiendo por
los ltimos)

call <direccion> <==> {pushl %eip; jmp <direccion>;}
ret <==> {popl %eip}

Instrucciones no vistas:
leal <- similar -> movl
decl <- similar -> resta
enter --> crea marcos de activacin para bloques anidados.
leave <- similar -> deshace lo hecho por enter
"Proporcin": enter/leave ~ call/ret
