NASM

La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la versión revisada el 9 de octubre de 2021; las comprobaciones requieren 27 ediciones .
NASM
Tipo de compilador
Autor Simón Tatham, Julian Hall
Desarrolladores H. Peter Anvin, Jim Kukunas, Cyrill Gorcunov, Frank B. Kotler
Escrito en C [1]
Sistema operativo Linux , MacOS , Windows , DOS , KolibriOS
Primera edición 1996
plataforma de hardware x86, x86_64
ultima versión 2.15.05 (28 de agosto de 2020)
Licencia LGPL , desde la versión 2.07 - licencia BSD simplificada
Sitio web nasm.es

NASM ( Netwide Assembler ) es un ensamblador gratuito ( licencia LGPL y BSD ) para la arquitectura Intel x86 . Se utiliza para escribir programas de 16, 32 y 64 bits.

Historia

NASM fue creado por Simon Tatham con Julian Hall y actualmente está siendo desarrollado por un pequeño equipo de desarrollo en SourceForge.net . Originalmente se lanzó bajo su propia licencia, pero esta licencia se cambió más tarde a GNU LGPL después de muchos problemas causados ​​por la elección de la licencia. A partir de la versión 2.07, la licencia se ha cambiado a una "BSD simplificada" (BSD de 2 cláusulas ).

NASM puede ejecutarse en plataformas que no sean x86, como SPARC y PowerPC , pero solo genera código para x86 y x86-64 [2] .

NASM compite con éxito con el estándar de ensamblador de gas en Linux y muchos otros sistemas UNIX . [3] [4] [5] NASM se considera de mejor calidad que el gas. [5] Además, el ensamblador de gas predeterminado [6] usa la sintaxis de AT&T , que está orientada a procesadores que no son de Intel, mientras que NASM usa una variante de la sintaxis tradicional de Intel para ensambladores x86 ; La sintaxis de Intel es utilizada por todos los ensambladores de DOS/Windows, por ejemplo , MASM , TASM , fasm .

Sintaxis del lenguaje

NASM utiliza la sintaxis de Intel para escribir instrucciones. Una oración en lenguaje ensamblador NASM (línea de programa) puede constar de los siguientes elementos:

Etiqueta Instrucción Operandos Comentario

Los operandos están separados por una coma. Puede utilizar cualquier número de caracteres de espacio en blanco antes de la cadena y después de la declaración. Un comentario comienza con un punto y coma y el final del comentario es el final de la línea. Se puede utilizar un comando o pseudocomando (directiva del compilador) como instrucción. Si la línea es muy larga, entonces se puede mover a la siguiente usando una barra invertida , \similar a como se hace en el lenguaje C.

Compilar y enlazar

NASM compila programas para varios sistemas operativos dentro de procesadores compatibles con x86. Al estar en un sistema operativo, puede compilar libremente un archivo ejecutable para otro.

La compilación de programas en NASM consta de dos pasos. El primero es el montaje , el segundo es la vinculación . En la etapa de ensamblaje, se crea el código objeto. Contiene el código de máquina del programa y los datos, de acuerdo con el código fuente , pero los identificadores (variables, símbolos) aún no están vinculados a las direcciones de memoria. En la etapa de enlace , se crea un archivo ejecutable (programa) a partir de uno o más módulos de objetos . La operación de enlace asocia identificadores definidos en el programa principal con identificadores definidos en otros módulos, después de lo cual todos los identificadores reciben direcciones de memoria finales o se asignan dinámicamente.

Para vincular archivos de objetos a ejecutables en Windows, puede usar el enlazador gratuito alink [4] (para programas de 64 bits, el enlazador GoLink), y en Linux, el enlazador ld, que está disponible en cualquier versión de este sistema operativo.

Para ensamblar el archivo, ingrese el siguiente comando:

nasm -f formato nombre de archivo -o salida

Instrucciones de salto

El compilador procesa el texto del programa en varias pasadas, de modo que las instrucciones de salto se pueden colocar antes de que se declaren las etiquetas correspondientes.

En los comandos de saltos condicionales e incondicionales ( jmp), se utiliza por defecto el tipo de salto cercano — near. Por lo tanto, si es posible un salto corto, para no sobrestimar el tamaño del programa con un byte extra, es necesario especificar específicamente el tipo de salto short. A partir de la versión 0.98.09b, se han agregado las opciones de optimización -Ox , que permiten optimizar automáticamente el tamaño de las instrucciones de bifurcación [7] , en versiones anteriores o sin tales opciones, el tamaño mínimo del programa solo se puede obtener modificando manualmente el código fuente.

Formato de archivo de salida

NASM admite muchos formatos de archivo de salida, entre ellos [8] :

  • bin  es un archivo de formato arbitrario, determinado únicamente por el código fuente . Adecuado tanto para archivos de datos como para módulos con código ejecutable, como cargadores de arranque, imágenes ROM , módulos de sistema operativo , controladores MS-DOS .SYS o ejecutables .COM .
  • obj  es un módulo de objetos en formato OMF compatible con MASM y TASM .
  • win32 y win64  es un módulo de objetos para código de 32 y 64 bits, compatible con los compiladores Win32 y Win64 de Microsoft .
  • aout  es un módulo de objeto en una variante del formato a.out utilizado en los primeros sistemas Linux .
  • aoutb  es la versión del formato a.out para BSD - sistemas operativos compatibles.
  • coff  es un módulo de objetos en formato COFF compatible con el enlazador DJGPP .
  • elf32 y elf64  es un módulo de objeto en los formatos ELF32 y ELF64 que utilizan Linux y Unix System V , incluidos Solaris x86, UnixWare y SCO Unix .

El formato del archivo de salida se puede especificar usando el modificador de línea de comando -f . Los formatos pueden extender la sintaxis de algunas instrucciones y agregar sus propias instrucciones.

Ejemplos de ¡Hola, mundo! » para diferentes sistemas operativos

Ejemplos de programas ¡Hola, mundo! , que muestra el mensaje apropiado y sale.

Para el sistema operativo Linux SECCIÓN .data msg db " ¡ Hola mundo ! " , 0xa len equ $ -msg SECCIÓN .text global _start ; _ el punto de entrada del programa _start: mov eax , 4 ; 'escribir' syscall mov ebx , 1 ; descripción del archivo 1 (salida estándar) mov ecx , mensaje ; puntero a datos mov edx , len ; cantidad de datos int 0x80 ; llamar al núcleo mov eax , 1 ; '_exit' llamada al sistema mov ebx , 0 ; código de salida cero (éxito) int 0x80 ; llamar al núcleo Para sistema operativo Linux (x64) inicio_global _ sección .text _start: mov rax , 1 ; la llamada al sistema 1 es escribir mov rdi , 1 ; el identificador de archivo 1 es stdout mov rsi , mensaje ; dirección de la cadena a la salida mov rdx , 13 ; número de bytes syscall ; invocar el sistema operativo para hacer la escritura mov eax , 60 ; la llamada al sistema 60 es exit xor rdi , rdi ; código de salida 0 syscall ; invocar sistema operativo para salir mensaje: db " Hola , mundo " , 10 ; tenga en cuenta la nueva línea al final Bajo sistema operativo DOS SECCIÓN .texto org 0x100 ; esta directiva es necesaria sólo en el caso de un archivo .com que no tiene secciones mov ah , 0x9 mov dx , hello int 0x21 mov ax , 0x4c00 ; ah == 0x4c al == 0x00 int 0x21 SECCIÓN .data hola DB " ¡Hola , mundo ! " , 0xd , 0xa , ' $ ' Para sistema operativo Windows (obj) % include ' WIN32N.INC ' EXTERN MessageBoxA Import MessageBoxA user32.dll EXTERN ExitProcess Import ExitProcess kernel32.dll SECTION CODE USE32 CLASS = CODE ..start: push UINT MB_OK push LPCTSTR title push LPCTSTR banner push HWND NULL call [ MessageBoxA ] push UINT NULL call [ ExitProcess ] SECCIÓN DATOS USO32 CLASE = DATOS banner db ' ¡Hola , mundo ! ' , 0xD , 0xA , 0 título db ' Hola ' , 0 Para sistema operativo Windows x64 (objetivo) ; Hello.asm EXTERN MessageBoxW EXTERN ExitProcess SECTION .text USE64 start: sub rsp , 28 h ; 32 bytes para la convención de llamada de Microsoft x64 "espacio de sombra" + 8 bytes para la alineación de la pila al límite de 16 bytes después de la llamada puesta en la pila 8 bytes de dirección de retorno xor rcx , rcx ; HWND hWnd = NULL lea rdx , [ banner ] ; LPCTSTR lpText = banner lea r8 , [ título ] ; LPCTSTR lpCaption = título xor r9 , r9 ; UINT uType = MB_OK call MessageBoxW ; MessageBox(hWnd, lpText, lpCaption, uType) xor rcx , rcx ; UINT uExitCode = 0 call ExitProcess ; ExitProcess(uExitCode) SECCIÓN .banner de datos dw __utf16__ ( ' ¡Hola , mundo ! ' ), 0 título dw __utf16__ ( ' ¡ Hola ! ' ), 0

>nasm -f win64 Hola.asm
>golink Hola.obj kernel32.dll user32.dll

Para el sistema operativo FreeBSD SECCIÓN .data msg db " ¡ Hola mundo ! " , 0xa len equ $ -msg SECCIÓN .text global _start ; _ el punto de entrada del programa _start: push dword len push dword msg push dword 1 ; 1 es el descriptor de archivo de stdout mov eax , 4 ; 4 es el syscall push eax 'escribir' ; debemos dejar un dword extra en la pila int 0x80 ; llamar al kernel add esp , 16 ; limpiar la pila push dword 0 ; 0 es el código de salida (éxito) mov eax , 1 ; 1 es el syscall push eax '_exit' ; dword extra en la pila int 0x80 ; llamar al núcleo ; sin limpieza - nunca volveremos Bajo el sistema operativo KolibriOS [9] bits 32 % incluyen ' mos.inc ' sección .text MOS_HEADER01 main , image_end , memory_end , stacktop , 0 , 0 main: redraw : call draw_window wait_event: MOS_WAITEVENT dec eax jz redibujar dec eax jz tecla ;botón presionado; solo tenemos un botón, cierre la tecla MOS_EXIT : ;tecla presionada, léala e ignore mov eax , MOS_SC_GETKEY int 0x40 jmp wait_event draw_window: MOS_STARTREDRAW xor eax , eax mov ebx , 10 * 65536 + 150 mov ecx , 40 * 65536 + 50 mov edx , 0x33FFFFFF mov edi , header int 0x40 ; define& draw window mov eax , MOS_SC_WRITETEXT mov ebx , 30 * 65536 + 10 mov ecx , 0x80000000 mov edx , string int 0x40 ; display string MOS_ENDREDRAW ret ' ' Hello string , data world header ' db ¡ Mundo ! ' , 0 image_end: sección .bss alignb 4 stack resb 1024 stacktop: memory_end:

Programas notables escritos en NASM

  • Asmutils  es un conjunto de utilidades del sistema para los sistemas operativos BSD, UnixWare, Solaris y AtheOS .
  • El proyecto AsmOS [10]  es un sistema operativo en ensamblador NASM (actualmente en desarrollo).

Notas

  1. El proyecto de código abierto de nasm en Open Hub: página de idiomas - 2006.
  2. 1.1 ¿Qué es NASM? (enlace no disponible) . El ensamblador de toda la red: NASM . Sitio oficial. - "NASM, es un ensamblador 80x86 y x86-64". Consultado el 14 de julio de 2010. Archivado desde el original el 18 de febrero de 2012. 
  3. Ensambladores para Linux: Comparación de GAS y NASM . Consultado el 14 de julio de 2010. Archivado desde el original el 16 de agosto de 2011.
  4. 1 2 Uso de NASM Assembly en Windows (enlace descendente) . Fecha de acceso: 17 de julio de 2010. Archivado desde el original el 20 de julio de 2009. 
  5. 1 2 Randall Hyde. ¿Qué ensamblador es el mejor?  (Inglés)  (enlace inaccesible) . Fecha de acceso: 18 de julio de 2010. Archivado desde el original el 18 de febrero de 2012.
  6. Soporte para la sintaxis de Intel llamada a través de la directiva especial .intel_syntax, apareció en gas-2.10; ver gas/NOTICIAS  (ing.)  (enlace descendente) . Fecha de acceso: 18 de julio de 2010. Archivado desde el original el 18 de febrero de 2012.
  7. C.2.33 Versión 0.98.09b con parches de John Coffman publicados el 28 de octubre de 2001 (enlace descendente) . El ensamblador de toda la red: NASM. Apéndice C: Historial de versiones de NASM . Sitio oficial. Fecha de acceso: 18 de julio de 2010. Archivado desde el original el 18 de febrero de 2012. 
  8. Capítulo 7: Formatos de salida (enlace descendente) . El ensamblador de toda la red: NASM . Sitio oficial. Consultado el 14 de julio de 2010. Archivado desde el original el 18 de febrero de 2012. 
  9. Uso de varios compiladores en Hummingbirds . Consultado el 10 de febrero de 2022. Archivado desde el original el 10 de febrero de 2022.
  10. Sistema operativo en ensamblador NASM . Consultado el 5 de julio de 2010. Archivado desde el original el 20 de octubre de 2011.

Literatura

Enlaces