jueves, 2 de agosto de 2012

Introducción a Netwide Assembler, Segunda parte

1. Estructuras de control de proceso
  • Qué son
  • Ejemplo

2. Subprocesos
  • La pila
  • Argumentos de pila
  • Llamada y retorno

3. Sintaxis NASM
  • Funciones globales
  • Carga de funciones externas
  • Secciones
  • Etiquetas
  • Esqueleto de un programa

4. NASM y GCC
  • Ejemplos
  • Ejercicio final

Estructuras de control de proceso

Qué son:
Las estructuras de control son procesos a alto nivel que realiza el compilador, con las que no contamos en ASM (A bajo nivel).

Estas estructuras pueden ser bucles (While, For, ...), comparaciones (if’s) y de ramificación.

Ejemplo:
Ejemplo de estos tres últimos tipos, en un comparador de cadenas:

global main
   
  extern printf
   
  segment .data
  smal  DB         `Diferentes\0`
  sbien DB         `Iguales\0`
  Cadena1         DB         `aaaa\0`
  Cadena2         DB         `aaaa\0`
   
  segment .bss
  len1  resb         12
  len2  resb         12
   
  segment .text
  main:
           PUSH      EBP
           MOV         EBP,ESP
           MOV         [ESP],dword Cadena1
           CALL         longitud
           MOV         dword[len1],EAX
           MOV         [ESP],dword Cadena2
           CALL         longitud
           MOV         dword[len2],EAX
           MOV         EAX,dword[len1]
           MOV         ECX,dword[len2]
           CMP         EAX,ECX
           JNE         Mal
           XOR         ECX,ECX
           MOV         EDX,dword[len1]
  Buclecmp:
           CMP         EDX,ECX
           JE         Bien
           MOV         AL,byte[Cadena1+ecx]
           MOV         BL,byte[Cadena2+ecx]
           CMP         AL,BL
           JNE         Mal
           INC         ECX
           JMP         Buclecmp
  Mal:
           PUSH      smal
           CALL       printf
           LEAVE
           RET
  Bien:
           PUSH      sbien
           CALL       printf
           LEAVE
           RET
  longitud:
           PUSH      EBP
           MOV         EBP,ESP
           SUB         ESP,4
           XOR         ECX,ECX
  BUCLE:
           LEA         EAX,[EBP+8]
           MOV         EAX,DWORD [EAX]
           MOV         BL,byte[EAX+ECX]
           CMP         BL,0
           JE         Retornar
           INC         ECX
           JMP         BUCLE
  Retornar:
           MOV         EAX,ECX
           LEAVE
           RET
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Subprocesos

Estamos por conocer más de cerca las instrucciones PUSH y POP.

La pila es una lista de memoria en la que podemos manejarnos. Para que no se creen confusiones, se trata del Stack. Cuando realizamos PUSH estamos cargando datos a la pila, mientras que con POP lo descargamos. PUSH empuja un dato, mientras que POP se encarga del último (L.I.F.O)

La instrucción PHSA empuja el contenido de los registros a la pila.

Al realizar una llamada a un subproceso (Función) mediante CALL, éstos deben estar de acuerdo en el número y valor de parámetros que vamos a precisar (Argumentos).

Los argumentos se almacenan en EBP+8, EBP+0xC y sucesivamente. Más allá de los parámetros recividos estaríamos tocando cosas que no deberíamos, y ya podrías imaginar el resultado.

Un ejemplo de esto lo podemos ver en el ejemplo anterior, en la llamada al subproceso longitud (Función longitud)

         MOV         [ESP],dword Cadena1 ;Cargar argumento, PUSH
         CALL         longitud
[etc]

longitud:
           PUSH      EBP
           MOV         EBP,ESP
           SUB         ESP,4
           XOR         ECX,ECX
  BUCLE:
           LEA         EAX,[EBP+8]         ;Obtenemos direccion
           MOV         EAX,DWORD [EAX] ;Leemos puntero
           MOV         BL,byte[EAX+ECX]
           CMP         BL,0
           JE         Retornar
           INC         ECX
           JMP         BUCLE
  Retornar:
           MOV         EAX,ECX
           LEAVE
           RET
 


El valor retornado siempre es almacenado en EAX. Realmente depende del programador, pero por regla general es así


Sintaxis NASM
Declaraciones globales

Funciones declaradas como globales, por ejemplo al usar C y NASM

Global main         ;Obligatorio
  Global funcion
Carga de funciones externas

Cargar funciones externas.

Extern printf
  Extern scanf
  Extern funcionpropia
Secciones

Son muchas, pero aquí van las más comunes.

.BSS – Datos no inicializados (Variables)
  .DATA – Datos inicializados (Constantes)
  .TEXT – Texto
.CODE – Código
Etiquetas

Son labels que usamos para determinar el salto hacia otra línea de código (o dirección). Recuerda a GOTO, todo un clásico
 

Bucle:
           CMP         EAX,0
           JNE         Bucle
           JMP         Fin
  Fin:
           RET





Esqueleto de un programa



global main
   
  extern Funcionacargar
   
  segment .data
  constante         DB         `Valor\0`
   
  segment .bss
  variable         resb         1024         ;Longitud
   
  segment .text
  main:
           PUSH      EBP
           MOV         EBP,ESP
           SUB         ESP,4
           LEAVE
           RET
 
 
 
NASM y GCC, Ejemplo de uso
 
Dejo el análisis a vosotros para comprobar lo aprendido hasta ahora... Se que me quieres
Subprocesos externos:

b.asm:

 
global main
   
  extern longitud
  extern printf
   
  segment .data
  ftoi   DB         `%i caracteres\0`
  Cadena         DB         `aaaaaaa\0`
   
  segment .text
  main:
           PUSH      EBP
           MOV         EBP,ESP
   
           MOV         [ESP],dword Cadena
           CALL         longitud
           PUSH      EAX
           PUSH      ftoi
           CALL       printf
           LEAVE
           RET
 



b.c:


#include <stdio.h>
   
  int longitud(char *s1)
  {
      return strlen(s1);
  }
Compilación:
nasm -f win32 -Wall --prefix _ b.asm
gcc -o b b.obj b.c
Ejercicio final:
Realizar una calculadora utilizando GCC y NASM, utilizando estructuras de control, subprocesos, retornos y la pila

Datos finales: Esperen la siguiente versión. Puntos flotantes, estructuras, matrices, ...

Agradecimientos: Jep, Swash, 11Sep, Shadowbyte, Mr.Blood, ...

Creado por: Yo-Mismo (Para oversec.org)

Las dudas las resuelvo por privado, no en el hilo (Mejor abrir tema nuevo.)

Un saludo!