NASM (Netwide Assembler) ist ein beliebter [[:Assembler]] für die x86-Architektur, der für seine Portabilität, Flexibilität und Effizienz bekannt ist. NASM wird häufig für die Entwicklung von Betriebssystemen, Treibern und anderen Systemsoftwarekomponenten verwendet, bei denen niedrige Latenz und direkter Zugriff auf die Hardware erforderlich sind. * Plattformunabhängigkeit: NASM kann auf verschiedenen Betriebssystemen wie Linux, Windows und macOS verwendet werden. * Modularität: NASM unterstützt verschiedene Ausgabeformate wie ELF, COFF, Mach-O und mehr, was die Erstellung von plattformübergreifender Software erleichtert. * Leichtgewicht: NASM ist ein schlankes und effizientes Werkzeug, das schnell und ressourcenschonend arbeitet. * Flexibilität: NASM unterstützt eine Vielzahl von x86- und x86-64-Instruktionen und bietet viele Direktiven zur Steuerung der Assemblerausgabe. =====Linux===== Hello World section .data hello db 'Hello, World!', 0 ; Null-terminierte Zeichenkette section .text global _start ; Der Entry-Point für das Programm _start: ; Syscall zum Schreiben (write) mov eax, 4 ; Syscall-Nummer für sys_write mov ebx, 1 ; File-Descriptor 1 - stdout mov ecx, hello ; Pointer auf die Zeichenkette mov edx, 13 ; Länge der Zeichenkette int 0x80 ; Interrupt um den Syscall auszuführen ; Syscall zum Beenden (exit) mov eax, 1 ; Syscall-Nummer für sys_exit xor ebx, ebx ; Rückgabewert 0 int 0x80 ; Interrupt um den Syscall auszuführen Kompilieren nasm -f elf32 -o hello.o hello.asm ld -m elf_i386 -s -o hello hello.o ./hello ====Addition==== section .data num1 db '5', 0 ; Null-terminierte Zeichenkette num2 db '7', 0 ; Null-terminierte Zeichenkette result db 'Result: 12', 0 section .bss temp resb 1 section .text global _start _start: ; Zahl 1 laden mov al, [num1] sub al, '0' ; ASCII zu Integer konvertieren ; Zahl 2 laden mov bl, [num2] sub bl, '0' ; ASCII zu Integer konvertieren ; Addition add al, bl ; Ergebnis in ASCII umwandeln add al, '0' mov [temp], al ; Ergebnis ausgeben mov edx, 9 ; Länge der Zeichenkette "Result: " mov ecx, result ; Pointer auf die Zeichenkette mov ebx, 1 ; File-Descriptor 1 - stdout mov eax, 4 ; Syscall-Nummer für sys_write int 0x80 ; Interrupt um den Syscall auszuführen ; Temp-Wert ausgeben mov edx, 1 ; Länge der Zeichenkette (1 Zeichen) mov ecx, temp ; Pointer auf die Zeichenkette mov ebx, 1 ; File-Descriptor 1 - stdout mov eax, 4 ; Syscall-Nummer für sys_write int 0x80 ; Interrupt um den Syscall auszuführen ; Programm beenden mov eax, 1 ; Syscall-Nummer für sys_exit xor ebx, ebx ; Rückgabewert 0 int 0x80 ; Interrupt um den Syscall auszuführen nasm -f elf32 -o addition.o addition.asm ld -m elf_i386 -s -o addition addition.o ./addition ====Loops==== section .data msg db 'Counting: ', 0 newline db 10, 0 section .bss counter resb 1 section .text global _start _start: mov ecx, 10 ; Anzahl der Wiederholungen print_msg: mov eax, 4 ; Syscall-Nummer für sys_write mov ebx, 1 ; File-Descriptor 1 - stdout mov edx, 10 ; Länge der Zeichenkette "Counting: " mov ecx, msg ; Pointer auf die Zeichenkette int 0x80 ; Interrupt um den Syscall auszuführen mov al, byte [counter] add al, '0' ; Integer zu ASCII konvertieren mov [counter], al ; Ausgabe des Zählers mov eax, 4 ; Syscall-Nummer für sys_write mov ebx, 1 ; File-Descriptor 1 - stdout mov ecx, counter ; Pointer auf die Zeichenkette mov edx, 1 ; Länge der Zeichenkette (1 Zeichen) int 0x80 ; Interrupt um den Syscall auszuführen ; Neue Zeile ausgeben mov eax, 4 ; Syscall-Nummer für sys_write mov ebx, 1 ; File-Descriptor 1 - stdout mov ecx, newline ; Pointer auf die Zeichenkette mov edx, 1 ; Länge der Zeichenkette (1 Zeichen) int 0x80 ; Interrupt um den Syscall auszuführen ; Zähler erhöhen inc byte [counter] ; Schleife loop print_msg ; Programm beenden mov eax, 1 ; Syscall-Nummer für sys_exit xor ebx, ebx ; Rückgabewert 0 int 0x80 ; Interrupt um den Syscall auszuführen nasm -f elf32 -o loop.o loop.asm ld -m elf_i386 -s -o loop loop.o ./loop =====Windows===== Hello World section .data hello db 'Hello, World!', 0 ; Null-terminierte Zeichenkette section .text global _start ; Der Entry-Point für das Programm _start: ; Syscall zum Schreiben (write) mov eax, 4 ; Syscall-Nummer für sys_write mov ebx, 1 ; File-Descriptor 1 - stdout mov ecx, hello ; Pointer auf die Zeichenkette mov edx, 13 ; Länge der Zeichenkette int 0x80 ; Interrupt um den Syscall auszuführen ; Syscall zum Beenden (exit) mov eax, 1 ; Syscall-Nummer für sys_exit xor ebx, ebx ; Rückgabewert 0 int 0x80 ; Interrupt um den Syscall auszuführen nasm -f win32 -o hello.obj hello.asm gcc -o hello.exe hello.obj hello.exe ====Addition==== section .data num1 db '5', 0 ; Null-terminierte Zeichenkette num2 db '7', 0 ; Null-terminierte Zeichenkette result db 'Result: 12', 0 section .bss temp resb 1 section .text global _start _start: ; Zahl 1 laden mov al, [num1] sub al, '0' ; ASCII zu Integer konvertieren ; Zahl 2 laden mov bl, [num2] sub bl, '0' ; ASCII zu Integer konvertieren ; Addition add al, bl ; Ergebnis in ASCII umwandeln add al, '0' mov [temp], al ; Ergebnis ausgeben mov edx, 9 ; Länge der Zeichenkette "Result: " mov ecx, result ; Pointer auf die Zeichenkette mov ebx, 1 ; File-Descriptor 1 - stdout mov eax, 4 ; Syscall-Nummer für sys_write int 0x80 ; Interrupt um den Syscall auszuführen ; Temp-Wert ausgeben mov edx, 1 ; Länge der Zeichenkette (1 Zeichen) mov ecx, temp ; Pointer auf die Zeichenkette mov ebx, 1 ; File-Descriptor 1 - stdout mov eax, 4 ; Syscall-Nummer für sys_write int 0x80 ; Interrupt um den Syscall auszuführen ; Programm beenden mov eax, 1 ; Syscall-Nummer für sys_exit xor ebx, ebx ; Rückgabewert 0 int 0x80 ; Interrupt um den Syscall auszuführen nasm -f win32 -o addition.obj addition.asm gcc -o addition.exe addition.obj addition.exe ====Loops==== section .data msg db 'Counting: ', 0 newline db 10, 0 section .bss counter resb 1 section .text global _start _start: mov ecx, 10 ; Anzahl der Wiederholungen print_msg: mov eax, 4 ; Syscall-Nummer für sys_write mov ebx, 1 ; File-Descriptor 1 - stdout mov edx, 10 ; Länge der Zeichenkette "Counting: " mov ecx, msg ; Pointer auf die Zeichenkette int 0x80 ; Interrupt um den Syscall auszuführen mov al, byte [counter] add al, '0' ; Integer zu ASCII konvertieren mov [counter], al ; Ausgabe des Zählers mov eax, 4 ; Syscall-Nummer für sys_write mov ebx, 1 ; File-Descriptor 1 - stdout mov ecx, counter ; Pointer auf die Zeichenkette mov edx, 1 ; Länge der Zeichenkette (1 Zeichen) int 0x80 ; Interrupt um den Syscall auszuführen ; Neue Zeile ausgeben mov eax, 4 ; Syscall-Nummer für sys_write mov ebx, 1 ; File-Descriptor 1 - stdout mov ecx, newline ; Pointer auf die Zeichenkette mov edx, 1 ; Länge der Zeichenkette (1 Zeichen) int 0x80 ; Interrupt um den Syscall auszuführen ; Zähler erhöhen inc byte [counter] ; Schleife loop print_msg ; Programm beenden mov eax, 1 ; Syscall-Nummer für sys_exit xor ebx, ebx ; Rückgabewert 0 int 0x80 ; Interrupt um den Syscall auszuführen nasm -f win32 -o loop.obj loop.asm gcc -o loop.exe loop.obj loop.exe =====Win32 API===== Hello World section .data hello db 'Hello, World!', 0 section .bss hStdOut resd 1 section .text extern _GetStdHandle@4, _WriteFile@20, _ExitProcess@4 global _main _main: ; GetStdHandle(STD_OUTPUT_HANDLE) push dword -11 call _GetStdHandle@4 mov [hStdOut], eax ; HANDLE hFile ; WriteFile(hFile, hello, 13, NULL, NULL) push dword 0 ; LPOVERLAPPED lpOverlapped push dword 0 ; LPDWORD lpNumberOfBytesWritten push dword 13 ; DWORD nNumberOfBytesToWrite push dword hello ; LPCVOID lpBuffer mov eax, [hStdOut] ; HANDLE hFile push eax call _WriteFile@20 ; ExitProcess(0) push dword 0 call _ExitProcess@4 nasm -f win32 -o hello.obj hello.asm gcc -o hello.exe hello.obj -lkernel32 hello.exe ====Addition==== section .data num1 db '5', 0 ; Null-terminierte Zeichenkette num2 db '7', 0 ; Null-terminierte Zeichenkette result db 'Result: ', 0 res resb 2 section .bss hStdOut resd 1 section .text extern _GetStdHandle@4, _WriteFile@20, _ExitProcess@4 global _main _main: ; Zahl 1 laden mov al, [num1] sub al, '0' ; ASCII zu Integer konvertieren ; Zahl 2 laden mov bl, [num2] sub bl, '0' ; ASCII zu Integer konvertieren ; Addition add al, bl ; Ergebnis in ASCII umwandeln add al, '0' mov [res], al mov byte [res+1], 0 ; GetStdHandle(STD_OUTPUT_HANDLE) push dword -11 call _GetStdHandle@4 mov [hStdOut], eax ; HANDLE hFile ; Result ausgeben push dword 0 ; LPOVERLAPPED lpOverlapped push dword 0 ; LPDWORD lpNumberOfBytesWritten push dword 9 ; DWORD nNumberOfBytesToWrite push dword result ; LPCVOID lpBuffer mov eax, [hStdOut] ; HANDLE hFile push eax call _WriteFile@20 ; Ergebnis ausgeben push dword 0 ; LPOVERLAPPED lpOverlapped push dword 0 ; LPDWORD lpNumberOfBytesWritten push dword 2 ; DWORD nNumberOfBytesToWrite push dword res ; LPCVOID lpBuffer mov eax, [hStdOut] ; HANDLE hFile push eax call _WriteFile@20 ; Programm beenden push dword 0 call _ExitProcess@4 nasm -f win32 -o addition.obj addition.asm gcc -o addition.exe addition.obj -lkernel32 addition.exe