miércoles, 5 de diciembre de 2018

Macros

Assembly - Macros

Resultado de imagen para macros

Escribir una macro es otra forma de asegurar la programación modular en lenguaje ensamblador.

Una macro es una secuencia de instrucciones, asignada por un nombre y podría usarse en cualquier parte del programa.

En NASM, las macros se definen con las directivas% macro y% endmacro.

La macro comienza con la directiva% macro y termina con la directiva% endmacro.

La sintaxis para la definición de macros -

%macro macro_name  number_of_params
<macro body>
%endmacro

Donde, number_of_params especifica los parámetros de número, macro_name especifica el nombre de la macro.

La macro se invoca utilizando el nombre de la macro junto con los parámetros necesarios. Cuando necesite usar una secuencia de instrucciones muchas veces en un programa, puede colocar esas instrucciones en una macro y usarlas en lugar de escribirlas todo el tiempo.

Por ejemplo, una necesidad muy común de programas es escribir una cadena de caracteres en la pantalla. Para mostrar una cadena de caracteres, necesita la siguiente secuencia de instrucciones:

mov	edx,len	    ;message length
mov	ecx,msg	    ;message to write
mov	ebx,1       ;file descriptor (stdout)
mov	eax,4       ;system call number (sys_write)
int	0x80        ;call kernel

En el ejemplo anterior de mostrar una cadena de caracteres, los registros EAX, EBX, ECX y EDX han sido utilizados por la llamada a la función INT 80H. Por lo tanto, cada vez que necesite mostrar en pantalla, debe guardar estos registros en la pila, invocar INT 80H y luego restaurar el valor original de los registros de la pila. Por lo tanto, podría ser útil escribir dos macros para guardar y restaurar datos.

Hemos observado que algunas instrucciones como IMUL, IDIV, INT, etc., necesitan que parte de la información se almacene en algunos registros particulares e incluso devuelva valores en algunos registros específicos. Si el programa ya estaba usando esos registros para mantener datos importantes, entonces los datos existentes de estos registros deben guardarse en la pila y restaurarse después de que se ejecute la instrucción.

Ejemplo

; A macro with two parameters
; Implements the write system call
   %macro write_string 2 
      mov   eax, 4
      mov   ebx, 1
      mov   ecx, %1
      mov   edx, %2
      int   80h
   %endmacro
 
section	.text
   global _start            ;must be declared for using gcc
	
_start:                     ;tell linker entry point
   write_string msg1, len1               
   write_string msg2, len2    
   write_string msg3, len3  
	
   mov eax,1                ;system call number (sys_exit)
   int 0x80                 ;call kernel

section	.data
msg1 db	'Hello, programmers!',0xA,0xD 	
len1 equ $ - msg1			

msg2 db 'Welcome to the world of,', 0xA,0xD 
len2 equ $- msg2 

msg3 db 'Linux assembly programming! '
len3 equ $- msg3

Cuando el código anterior se compila y ejecuta, produce el siguiente resultado:

Hello, programmers!
Welcome to the world of,
Linux assembly programming!

0 comentarios:

Publicar un comentario