Comenzando con GNU Assembler (GAS)


En estas semanas en la UNIversidad estuve viendo lo que es un poco de assembler, pero sucede que cuando se explica se usa herramientas privativas como NASM, por lo cual decidí buscar herramientas libres y encontré que existía GNU Assembler (GAS) dentro del sistema GNU, el cual usa la sintaxis de AT&T, así que decidí aprender el uso de GAS y ahora procederé a explicar un par de ejemplos.

En este articulo explicare sobre imprimir una cadena, macros y algunas otras cositas que encontré por ahí. Tener en claro que esto lo he aprendido de diferentes códigos, ya que encontré poca información en la red, así que si me equivoco en algún concepto por favor díganmelo.

Cada código para poder tenerlo como ejecutable, deberemos de ensamblarlo (volverlo a código objeto «.o») y luego Vincularlo (volverlo ejecutable). Para esto haremos los siguientes comandos en la consola con cada ejemplo encontrado debajo.

Primero lo ensamblamos:

as –o programa.o programa.s

Segundo lo vinculamos:

ld –o programa programa.o

Al final los ejecutamos:

./programa

Ejemplo1

#Definimos el segmento de datos
.section .data
	mensaje: .ascii "Hola Urpi\n" #Definimos una variable mensaje
	longitud = . - mensaje #Definimos la longitud de mensaje

#Definimos el segmento de texto
.section .text
	.globl _start #Le damos el punto de entrada _start

_start:
	movl $longitud, %edx #Asignamos longitud a edx
	movl $mensaje,%ecx #Asignamos mensaje a edx
	movl $1,%ebx
	movl $4,%eax
	int $0x80 #Similar a la llamada 21 del MS-DOS

	#Terminamos el programa
	movl $0,%ebx
	movl $1,%eax
	int $0x80 #Llamando al kernel

En el ejemplo1 usamos la sección (similar a segmento) «data» para definir variables, dentro de la sección «text» vamos a poner el código en si, cabe notar también que ahora es movl en lugar de mov y que el orden es inverso y ahora se usa «%» antes de llamar a los registros, los comentarios se pueden hacer con «//», «#» o «/* … */» (sin las comillas), entre algunas otras diferencias.

Ejemplo2

#Creamos un macro para definir la funcion imprimir
.macro imprimir cadena longitud
	movl \longitud,%edx
	movl \cadena,%ecx
	movl $1,%ebx
	movl $4,%eax
	int $0x80
.endm

.macro terminar
	movl $0,%ebx
	movl $1,%eax
	int $0x80 #Llamando al kernel
.endm

#Definimos el segmento de datos
.section .data
	msg_saludo: .ascii "Hola Urpi\n" #Definimos una variable mensaje
	long_saludo = . - msg_saludo #Definimos la longitud de mensaje
	msg_email: .ascii "To correo es : ovegar (at) uni (dot) pe\n"
	long_email = . - msg_email

#Definimos el segmento de texto
.section .text
	.globl _start #Le damos el punto de entrada _start

_start:
	imprimir $msg_saludo $long_saludo #Mandamos msg_saludo y long_saludo al macro imprimir
	imprimir $msg_email $long_email
	terminar #Terminamos el programa, el codigo ahora esta en el macro terminar

En el ejemplo2 ahora necesitamos imprimir dos cadenas y como usaremos código de manera repetitiva código, entonces crearemos macros que vendría a ser similar a funciones.

Se puede encontrar información para poder iniciar en esta web de IBM.