Analizando primer programa

Posted by Labels: at


 El hola mundo

Ejecutamos el siguiente programa


section .data

    msg db "Hello world!", 0ah

section .text

    global _start

_start:

    mov rax, 1

    mov rdi, 1

    mov rsi, msg

    mov rdx, 13

    syscall

    mov rax, 60

    mov rdi, 0

    syscall

Ahora analizaremos linea por linea

section. Define una sección dentro del fichero de código fuente. Cada sección hará referencia a un segmento de memoria diferente dentro del espacio de memoria asignado al programa. Hay tres tipos de secciones:
a) .data: sección en la que se definen datos inicializados, datos a los que damos un valor inicial.
b) .bss: sección en la que se definen datos sin inicializar.
c) .text: sección en la que se incluyen las instrucciones del programa.
La utilización de estas directivas no es imprescindible, pero sí recomendable con el fin de definir los diferentes tipos de información que utilizaremos.

             Sección de data 

section .data

msg db "Hello world!", 0ah                  ;0ah es el caracter de escapa para un salto de linea

                                                                 


La sección de texto es de solo lectura en la mayoría de los sistemas operativos, por lo que es posible que necesite una sección de data. En la mayoría de los sistemas operativos, la sección de datos es solo para datos inicializados y tiene una sección especial .bss para datos no inicializados.

Datos inicializados DB, DW, DD, DQ, DT, DO, DY y DZ (colectivamente "Dx") se utilizan, para declarar datos inicializados en el archivo de salida. 

Se pueden invocar en una amplia gama de formas:   

db    0x55                             ; solo el byte 0x55   

db    0x55,0x56,0x57           ; tres bytes seguidos   

db    'a',0x55                         ; las constantes de caracteres están bien     

db    'hello',13,10,'$'             ; también lo estan las constantes de cadena      

dw    0x1234                        ; 0x34 0x12  

dw    'a'                                 ; 0x61 0x00 (es solo un número)      

dw    'ab'                               ; 0x61 0x62 (caracter constante)      

dw    'abc'                             ; 0x61 0x62 0x63 0x00 (cadena)     

dd    0x12345678                 ; 0x78 0x56 0x34 0x12     

dd    1.234567e20                ; constante de punto flotante      

dq    0x123456789abcdef0  ; constante de ocho bytes      

dq    1.234567e20                ; flotante de doble precisión      

dt    1.234567e20                 ; flotante de precisión extendida


Constantes STRINGS

Las constantes STRINGS son cadenas de caracteres que se usan en el contexto 

de algunas pseudoinstrucciones, a saber, 

la familia DB e INCBIN (donde representa un nombre de archivo). 

También se usan en ciertas directivas de preprocesador.

Una constante de cadena se parece a una constante de carácter, solo que más larga. Se trata como una concatenación de constantes de caracteres de tamaño máximo para las condiciones. Entonces los siguientes son equivalentes:  

   db    'hello'               ; string constant     

   db    'h','e','l','l','o'   ; equivalent character constants

Las siguientes declaraciones también son equivalentes:

    dd    'ninechars'           ; doubleword string constante

    dd    'nine','char','s'     ; se convierte en tres doublewords 

    db    'ninechars',0,0,0     ; y realmente se parece a esto


Nota: 

Tenga en cuenta que, cuando se utilizan en un contexto que admite cadenas,

 las cadenas entre comillas se tratan como constantes de cadena incluso si

 son lo suficientemente cortas como para ser una constante de carácter.


Llamadas al sistema


mov rax, 1        llamada al sistema con el numero 1 para escribir


Algunos ejemplos de llamadas al sistema son las siguientes:

 write, que se emplea para escribir un dato en un cierto dispositivo de salida, tales como una pantalla o un disco magnético.

 read, que es usada para leer de un dispositivo de entrada, tales como un teclado o un disco magnético.

 open, que es usada para obtener un descriptor de un fichero del sistema, ese fichero suele pasarse a write.

 close, que se emplea para cerrar un descriptor de fichero.

Todo sistema operativo ofrece un conjunto de llamadas al sistema. En el caso de Linux se ofrecen un total de 345 llamadas al sistema

Toda llamada al sistema se identifica de manera unívoca mediante un valor numérico que no debe ser modificado a lo largo de la vida del sistema operativo para evitar que se rompa la compatibilidad hacia atrás.  

    mov rdi, 1  ; el identificador de archivo 1 es stdout 


    mov rsi, msg  ;  Aquí se guarda la dirección del mensaje es decir la variable db msg 


    mov rdx, 13    ; Es el numero de bytes que vamos a tomar de msg


Para realizar una llamada al sistema en Linux de 64 bits, se coloca el número de llamada del sistema en rax, luego sus argumentos, en orden, en rdi, rsi, rdx, r10, r8y r9, luego invoque syscall.

Algunas llamadas al sistema devuelven información, normalmente en formato rax. Un valor en el rango entre -4095 y -1 indica un error.

    syscall

Como vemos en el registro rax le dimos el valor 1 para hacer una escritura. Luego los parametros de la llamada se escriben en rdi, rsi y rdx en ese orden, los registros r10, r8 y r9 no involucran argumentos para esta llamada.

Syscall es la llamada al sistema, en versión de 32 bits se usaria la interrupción 80 (int 80h), en 64 bits esto tambien es soportado pero se usa syscall para simplificar.

Terminación del programa 

Para terminar la ejecución del programa y retornar al sistema operativo usamos el código 60 que es el código de salida, 

    mov rax, 60     ; invocar al sistema operativo para salir

Retornamos el código de salida 0

    mov rdi, 0      

Seguirian los otros registros en el orden correcto pero no hacen falta para esta llamada.

    syscall

Al final se hace de nuevo la llamada al sistema 


Anexo: tabla de llamadas al sistema para rax

Back to Top