Pierwszy program Linux 32-bit (Pokaż/ukryj kod)
; NASM 32 bit: program zapisany w pliku hello.asm ; kompilacja: nasm -felf hello.asm -o hello.o ; linkowanie: ld hello.o -o hello ; linkowanie w systemach 64-bit: ld -m elf_i386 hello.o -o hello section .text global _start ; linux rozpoczyna wykonywanie programu od etykiety _start _start: ; musi ona być widoczna na zewnątrz (global) mov eax, 4 ; numer funkcji systemowej: ; sys_write - zapisz do pliku mov ebx, 1 ; numer pliku, do którego piszemy. ; 1 = standardowe wyjście = ekran mov ecx, tekst ; ECX = adres (offset) tekstu mov edx, dlugosc ; EDX = długość tekstu int 80h ; wywołujemy funkcję systemową mov eax, 1 ; numer funkcji systemowej ; (sys_exit - wyjdź z programu) int 80h ; wywołujemy funkcję systemową section .data ; początek sekcji danych. tekst db "Czesc", 0ah ; nasz napis, który wyświetlimy dlugosc equ $ - tekst ; długość napisu
Pierwszy program Linux 64-bit (Pokaż/ukryj kod)
; wersja NASM na system 64-bitowy (x86-64) ; kompilacja: nasm -felf64 hello64.asm -o hello64.o ; linkowanie: ld hello64.o -o hello64 bits 64 section .text ; początek sekcji kodu. global _start ; linux rozpoczyna wykonywanie programu od etykiety _start ; musi ona być widoczna na zewnątrz (global) _start: ; punkt startu programu mov rax, 1 ; numer funkcji systemowej: ; sys_write - zapisz do pliku mov rdi, 1 ; numer pliku, do którego piszemy. ; 1 = standardowe wyjście = ekran mov rsi, tekst ; RSI = adres (offset) tekstu mov rdx, dlugosc ; RDX = długość tekstu syscall ; wywołujemy funkcję systemową mov rax, 60 ; numer funkcji systemowej ; (sys_exit - wyjdź z programu) syscall ; wywołujemy funkcję systemową section .data ; początek sekcji danych. tekst db "Czesc", 0ah ; nasz napis, który wyświetlimy dlugosc equ $ - tekst ; długość napisu
Pierwszy program Windows (Pokaż/ukryj kod)
; wersja NASM: program zapisany w pliku tekstowym a.asm ; kompilacja: nasm -fbin -o a.com a.asm org 0x100 section .data ; sekcja danych zainicjalizowanych info: db "Hello world!",13, 10, '$' ; ciąg znaków zakończony znakiem dolara - wymagane przez funkcję ; o numerze 9, wyświetlającą ciąg, znaki 10 i 13 dają nową linię section .bss ; sekcja danych niezainicjalizowanych bufor: resb 5 ; bufor 5 bajtów section .text ; sekcja kodu mov ah, 9 mov dx, info int 0x21 ; wywołaj przerwanie 0x21 - po załadowaniu 9 do AH wyświetlona będzie ; zawartość rejestru DX mov ah,0 int 0x16 ; wywołaj przerwanie 0x16 - po załadowaniu 0 do AH program czeka ; na naciśnięcie klawisza mov ax, 0x4C00 ; wyjście z programu z kodem błędu 0: w AH wpisane 4C, w AL wpisane 00, ; czyli kod wyjścia int 0x21
Wybrane sekcje zdefiniowane dla formatu elf
section .text progbits alloc exec nowrite align=16 section .data progbits alloc noexec write align=4 section .bss nobits alloc noexec write align=4 section .comment progbits noalloc noexec nowrite align=1 section other progbits alloc noexec nowrite align=1
Do definiowania zainicjowanych danych używamy pseudoinstrukcji
db, dw, dd, dq, dt, do
w zależności od wielkości danych
db 0x55 ; just the byte 0x55 db 0x55,0x56,0x57 ; three bytes in succession db 'a',0x55 ; character constants are OK db 'hello',13,10,'$' ; so are string constants dw 0x1234 ; 0x34 0x12 dw 'a' ; 0x61 0x00 (it's just a number) dw 'ab' ; 0x61 0x62 (character constant) dw 'abc' ; 0x61 0x62 0x63 0x00 (string) dd 0x12345678 ; 0x78 0x56 0x34 0x12 dd 1.234567e20 ; floating-point constant dq 0x123456789abcdef0 ; eight byte constant dq 1.234567e20 ; double-precision float dt 1.234567e20 ; extended-precision float
Do definiowania niezainicjowanych danych używamy
resb, resw, resd, resq, rest, resow zależności od wielkości danych.
buffer: resb 64 ; reserve 64 bytes wordvar: resw 1 ; reserve a word realarray: resq 10 ; array of ten reals ymmval: resy 1 ; one YMM register
Do definiowania stałych służy equ.
message db 'hello, world' msglen equ $-message
Specjalny symbol $ ewaluuje do adresu początku obecnej lini.
Dowolną instrukcję czy pseudoinstrukcje możemy wykonać wielokrotnie dzięki times.
; inicjuje 64 bajty wartościa 0 zerobuf: times 64 db 0 ; uzupełnia buffor aby zajmował dokladnie 64 bajty bufor: db 'hello, world' times 64-$+bufor db ' '
Specjalny symbol $ ewaluuje do adresu początku obecnej lini.