Diferencias
Muestra las diferencias entre dos versiones de la página.
Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
td3:guiasupervivenciaasm [2013/05/08 03:46] cnigri áéóíú Version borrador |
— (actual) | ||
---|---|---|---|
Línea 1: | Línea 1: | ||
- | ====== Guía de supervivencia de ensamblador ====== | ||
- | {{ td3: | ||
- | ===== Descargo ===== | ||
- | La redacción de una guía que permita aprender el lenguaje ensamblador es una tarea que no escapa al principio de incertidumbre de Heisenberg\\ | ||
- | \\ //Si el lenguaje se enseña rápidamente, | ||
- | \\ Para los menos amantes de la cuántica se puede decir que una guía de supervivencia de lenguaje ensamblador, | ||
- | \\ Por lo expresado de manera irónica en los párrafos anteriores, esta guía no pretende ser un texto que trate de forma exhaustiva los por menores del lenguaje ensamblador detallando el basto conjunto de instrucciones de la [[http:// | ||
- | |||
- | ===== Introducción ===== | ||
- | Esta guía solo cubre la sintaxis NASM y el conjunto de instrucciones IA32 | ||
- | |||
- | ===== Registros de la familia IA ===== | ||
- | ===== Instrucciones básicas ===== | ||
- | * Asignación: | ||
- | <code asm> mov ;Move </ | ||
- | * Comparación: | ||
- | <code asm> | ||
- | cmp ; | ||
- | test ;Logical Compare | ||
- | </ | ||
- | * Salto: | ||
- | * Condicionales en función del estado de un bit de bandera particular | ||
- | <code asm> | ||
- | * Absolutos | ||
- | <code asm> | ||
- | jmp ;Jump near/long | ||
- | </ | ||
- | * Binarias: operan bit a bit | ||
- | <code asm> | ||
- | and ; | ||
- | or ;Logical Inclusive OR | ||
- | xor ; | ||
- | not ; | ||
- | </ | ||
- | * Aritméticas: | ||
- | <code asm> | ||
- | add ;Add | ||
- | adc ;Add with Carry | ||
- | sub ; | ||
- | sbb ; | ||
- | inc ; | ||
- | dec ; | ||
- | clc ; | ||
- | mul ; | ||
- | div ; | ||
- | </ | ||
- | * Stack: operan con la pila, introduciendo y recuperando valores | ||
- | <code asm> | ||
- | pop ;Pop a Value from the Stack | ||
- | push ;Push Word, Doubleword or Quadword onto the Stack | ||
- | popf ;Pop Stack into FLAGS Register | ||
- | pushf ;Push FLAGS Register onto the Stack | ||
- | popad ;Pop All General-Purpose Registers | ||
- | </ | ||
- | * Desplazamiento: | ||
- | <code asm> | ||
- | shr ; | ||
- | shl ; | ||
- | ror ; | ||
- | rol ; | ||
- | </ | ||
- | ===== Constantes, variables y tipos ===== | ||
- | ==== Constantes ==== | ||
- | La definición de un simbolo asociado a una constante se realiza mediante la pseudo instrucción **//EQU//** | ||
- | <code asm> SEL_CODE EQU 0x08 ;El simbolo SEL_CODE se reemplazara en cada uso por el valor 0x08</ | ||
- | |||
- | ==== Variables ==== | ||
- | En ensamblador el concepto de variable es meramente figurativo, ya que esta no es más que un espacio identificado en memoria. Analicémoslo mediante los siguientes ejemplos: | ||
- | * Tomando la analogía con el bien conocido lenguaje C, si se quiere definir un **// | ||
- | <code asm> Mi_var_char resb 1 ; | ||
- | |||
- | Si además de definir la variable se quiere inicializar, | ||
- | <code asm> Mi_var_char db 0xA5 ;Variable inicializada </ | ||
- | |||
- | * Aplicando el mismo criterio se utilizan **//resw, resq, rest, dw, dq, dt//** | ||
- | <code asm> | ||
- | Mi_var_short resw 1 ; | ||
- | Mi_var_short resb 2 ;Otra opcion de lo anterior | ||
- | Mi_var_long | ||
- | Mi_var_long | ||
- | </ | ||
- | |||
- | ==== Tipos ==== | ||
- | En ciertas ocasiones es conveniente disponer de un arreglo de memoria con un formato específico, | ||
- | <code asm> | ||
- | struc | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | endstruc | ||
- | </ | ||
- | |||
- | Al igual que una variable, una estructura puede ser instanciada con o sin inialización, | ||
- | <code asm> | ||
- | Gdt_desc_nulo: | ||
- | at gdtd_t.limite, | ||
- | at gdtd_t.base00_15, | ||
- | at gdtd_t.base16_23, | ||
- | at gdtd_t.prop, | ||
- | at gdtd_t.lim_prop, | ||
- | at gdtd_t.base24_31, | ||
- | | ||
- | |||
- | Gdt_desc_extra: | ||
- | | ||
- | </ | ||
- | |||
- | Debido a que la carga de un valor en un campo de una estructura requiere cierta lógica, la misma se explica a continuación mediante un simple ejemplo, utilizando la estructura instanciada previamente. | ||
- | <code asm> mov [Gdt_desc_extra+gdtd_t.base00_15], | ||
- | |||
- | Como se explicara anteriormente, | ||
- | |||
- | ===== Macros ===== | ||
- | En los apartados precedentes se indicó que el preprocesador utilizaba macros para realizar ciertas definiciones, | ||
- | A modo de recordatorio se define como //macro una secuencia de instrucciones que pueden ser invocadas mediante una única sentencia// | ||
- | A diferencia de las funciones la utilización de macros genera un incremento en el tamaño del código y por ende en el binario final, sin embargo tienen la ventaja de aumentar la legibilidad del código y por lo general aumentar la velocidad de ejecución respecto al mismo código implementado por función. | ||
- | Por lo general existen dos tipos de macros | ||
- | * Linea simple: es el caso más básico de macros, el cual permite realizar la definición en una única línea utilizando la directiva %define. | ||
- | * Lineas múltiples: permite realizar secuencias más complejas y emplea las directivas **// | ||
- | |||
- | Como es costumbre se explicará la utilización de macros mediante un ejemplo, el cual tiene por objetivo inicializar la instancia // | ||
- | El primer paso es definir la macro | ||
- | * **gdtdescini: | ||
- | * **Argumento 1:** Direccion de la base del segmento. Valor maximo soportado 2^32. | ||
- | * **Argumento 2:** Tamaño del segmento. Valor maximo soportado 2^20. | ||
- | * **Argumento 3:** Propiedades P; | ||
- | * **Argumento 4:** Propiedades G;D/B;L;AVL | ||
- | * **Argumento 5:** Direccion de inicio del descriptor a ser inicializado. | ||
- | |||
- | <code asm> | ||
- | %macro gdtdescini 5 ;Nombre y numero de argumentos | ||
- | push ebx ;Se almacena el valor del registro | ||
- | xor ebx, ebx | ||
- | | ||
- | mov ebx, %1 ;Se carga EL PRIMER ARGUMENTO (la direccion) en ebx | ||
- | mov [%5+gdtd_t.base00_15], | ||
- | shr ebx, 16 | ||
- | mov [%5+gdtd_t.base16_23], | ||
- | |||
- | xor ebx, ebx | ||
- | mov ebx, %2 ;Se carga EL SEGUNDO ARGUMENTO EN ebx | ||
- | mov [%5+gdtd_t.limite], | ||
- | shr ebx, 16 ;Se adapta el restante nibble y | ||
- | mov [%5+gdtd_t.lim_prop], | ||
- | |||
- | xor bl, bl | ||
- | mov bl, %3 ;Se carga el primer byte | ||
- | mov [%5+gdtd_t.prop], | ||
- | |||
- | xor bl, bl | ||
- | mov bl, %4 ;Se carga el nibble EL CUARTO ARGUMENTO | ||
- | shl bl, 4 ;Se desplaza al nibble mas significativo | ||
- | or [%5+gdtd_t.prop], | ||
- | |||
- | pop ebx | ||
- | %endmacro | ||
- | </ | ||
- | |||
- | La utilización es extremadamente sencilla, por ejemplo si se quisiera inicializar el descriptor mencionado anteriormente para direccionar la memoria de video, bastaría con el siguiente codigo | ||
- | <code asm> gdtdescini 0B8000h, 4000, 10010011b, 0b, Gdt_desc_extra </ | ||
- | |||
- | ===== Referencias ===== | ||
- | * [[http:// | ||
- | * [[http:// | ||
- | * [[http:// | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||