En esta liga podemos ver teoria sobre el lenguaje Assembly.
Que necesitamos?
- un ensamblador para pasar nuestro codigo Assembly a un formato objeto.
- un enlazador que combine nuestros archivos objeto con las librerias necesarias.
En este caso utilizaremos assembly con sintaxis de Intel, ya que a mi parecer es un codigo muy limpio. Nuestro ensamblador sera NASM ya que es propio del uso de la sintaxis de Intel para 16 y 32 bits.
Nuestro enlazador por fortuna viene agregado como herramienta de GNU en sistemas con nucleo linux, su nombre es ld.
Como instalar NASM?
NASM esta en los repositorios de muchas distribuciones, solo se tiene que usar el comando del gestor de paquetes como ejemplo para debian/ubuntu:
sudo apt-get install nasm
y como mencionamos el enlazador viene por default.
Ahora veamos un Hola escrito para lenguaje assembly utilizando sintaxis Intel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Asi se hacen los comentarios. | |
SECTION .data ;Definimos la seccion de datos estaticos, equivalentes de constantes. | |
msg: db "Hola clase (:",10,13 ;etiqueta: db (DefineByte) "cadena",bytes sin formato, 10 = fin de linea, 13 = salto de linea | |
lon: equ $-$$ ;etiqueta: equ (EQUAL) cantidad. Es el equivalente de #define en lenguaje C | |
;$ es para la posicion actual del puntero en la ejecuccion desde que se inicio la seccion. | |
;$$ es para ver la posicion inicial desde la seccion. (donde estoy - donde estaba) | |
SECTION .text | |
;seccion text, aqui es donde va el codigo | |
global _start ;etiqueta para el enlazador | |
_start: ;punto de entrada para el enlazador ( funcion main ) | |
mov edx,lon ;Registro D, aqui guardaremos la longuitud de la cadena a imprimir | |
mov ecx,msg ;Registro C, aqui pondremos el puntero a los caracteres. | |
mov ebx,1 ;Registro B, aqui le ponemos el descriptor del archivo ( recordando que en unix todo es un archivo ) 1 =STDOUT | |
mov eax,4 ;Registro A, numero de comando 4=sys_write | |
int 0x80 ;interrupcion 80, llama al kernel y ejecuta la llamada que este en el acumulador | |
mov ebx,0 ;salida del codigo al sistema operativo | |
mov eax,1 ;numero de comando 1 = sys_exit | |
int 0x80 ;interrumpcion 80 hex, llama al kernel | |
Ahora lo ensamblaremos y lo enlazaremos con sus librerias para que nos quede un ejecutable.
Asi se hace una impresion utilizando Assembly con sintaxis intel sobre linux.
Dejando en claro cada linea de este programa.
SECTION .data es una seccion del programa que especifica la memoria del segmento de datos. Solo los datos iniciados se deber definir en este segmento.
En este segmento utilizamos db para reservar bytes, usamos la etiqueta msg para despues guardar caracteres " H "," o "," l "... y ademas le agregamos dos caracteres de escape ( 10 y 13 ) para estetica. Ademas utilizamos otra etiqueta llamada lon para guardarle un numero que comprende de la resta de la posicion actual del puntero menos la posicion inicial del puntero, si no fallo seria un 15.
MOV nos permite mover valores hacia los registros.
INT hace la llamada a una interrupcion y en este caso usamos la 0x80 que nos permite decirle al kernel que ejecute una llamada al sistema dependiendo de acumulador.
Ahora veremos otro programa que apartir de un argumento crea un nuevo archivo, le escribe una linea de caracteres predefinida.
Despues reabre el archivo, toma lectura de una linea y la imprime en pantalla.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
section .data | |
line db "hola esto es una linea de prueba",10 | |
len equ $ - $$ | |
section .bss ;Block Started by Symbol | |
buffer: resb len | |
file: resb 4 | |
num: resb 4 | |
section .text | |
global _start | |
_start: | |
pop ebx ;saca el ultimo dato de la pila, en este caso el # de argumentos | |
cmp ebx,3 ;juzga ebx para ver cuantos argumentos se pasaron | |
jne error ;salta si no es igual o es cero | |
pop ebx ;saca el siguiente, es el nombre del ejecutable | |
pop ebx ;saca el siguiente, es el argumento[1]. | |
cmp ebx,0 ;compara si no esta vacio | |
jbe error ;salta si no es 1. | |
mov [file], ebx ;lo que esta en ebx, muevelo a file, uso de corchetes para contenidos, no punteros. | |
mov eax,8 ;llamada creat | |
mov ecx,511 ;permisos para lectura y de ejecuccion | |
int 0x80 | |
mov eax,5 ;llamada sys_open | |
mov ebx,[file] ;nombre del archivo | |
mov ecx,1 ;1 = Escritura, 0 = Lectura | |
int 0x80 | |
mov ebx,eax ;guarda el file descriptor en EBX, ya que el sistema nos lo regresa en EAX | |
mov eax, 4 ;sys_write | |
mov edx, len ;mensaje | |
mov ecx, line ;size | |
int 0x80 | |
mov eax, 6 ;sys_close | |
int 0x80 | |
mov eax, 5 ;sys_open file with filedescriptor in ebx | |
mov ebx, [file] ;archivo que se abrira | |
mov ecx, 0 ;O_RDONLY zero es para solo lectura | |
int 0x80 | |
cmp eax, 0 ;checa que el filedescriptor en EAX sea mayor a 0 | |
jbe error ;no se abrio el archivo | |
mov ebx, eax ;guarda el file descrip | |
;; leer desde el archivo al .bss buffer para desplegarlo en pantalla | |
mov eax, 3 ;sys_read | |
mov ecx, buffer ;puntero a la variable buffer | |
mov edx, len ;size de los datos a leer. | |
int 0x80 | |
js error ;Error de lectura | |
cmp eax, len ;checa si no tubo una lectura menor a la requerida por len | |
jb close | |
mov eax, 4 ;sys_write | |
push ebx ;save file descriptor en pila for sys_close | |
mov ebx, 2 ;file descriptor de stderr que es ilimitada | |
mov ecx, buffer ;puntero al buffer con data | |
mov edx, len ;size de los datos | |
int 0x80 | |
pop ebx ;recupera filedescriptor en ebx de la pila | |
close: | |
mov eax, 6 ;sys_close file con | |
int 0x80 | |
mov eax, 1 ;sys_exit | |
mov ebx, 0 ;ok | |
int 0x80 | |
error: | |
mov ebx, eax ;exit code = sys call result | |
mov eax, 1 ;sys_exit | |
int 0x80 |
Manual para uso de NASM
Aqui les dejo la tabla de las llamadas al sistema