Netwide Assembler sample programs
Jump to navigation
Jump to search
Was this page created by accident or as a test? Please improve the educational quality of this page, and clarify what the intentions are on the discussion page so other people may contribute. The page might be able to remain at Wikibooks after 7 days when further development is likely.
Please consider notifying the author(s) with {{subst:Query notice|Netwide Assembler sample programs|~~~~}} |
This is a collection of sample programs for the Netwide Assembler.
A "Hello, world!" program for the DOS operating system:
section .text
org 0x100
mov ah, 0x9
mov dx, hello
int 0x21
mov ax, 0x4c00
int 0x21
section .data
hello: db 'Hello, world!', 13, 10, '$'
An equivalent program for Linux:
global _start
section .text
_start:
mov eax, 4 ; write
mov ebx, 1 ; stdout
mov ecx, msg
mov edx, msg.len
int 0x80 ; write(stdout, msg, strlen(msg));
xor eax, msg.len ; invert return value from write()
xchg eax, ebx ; value for exit()
mov eax, 1 ; exit
int 0x80 ; exit(...)
section .data
msg: db "Hello, world!", 10
.len: equ $ - msg
An example of a similar program for Microsoft Windows:
global _main
extern _MessageBoxA@16
extern _ExitProcess@4
section code use32 class=code
_main:
push dword 0 ; UINT uType = MB_OK
push dword title ; LPCSTR lpCaption
push dword banner ; LPCSTR lpText
push dword 0 ; HWND hWnd = NULL
call _MessageBoxA@16
push dword 0 ; UINT uExitCode
call _ExitProcess@4
section data use32 class=data
banner: db 'Hello, world!', 0
title: db 'Hello', 0
A 64-bit program for Apple OS X that inputs a keystroke and shows it on the screen:
global _start
section .data
query_string: db "Enter a character: "
query_string_len: equ $ - query_string
out_string: db "You have input: "
out_string_len: equ $ - out_string
section .bss
in_char: resw 4
section .text
_start:
mov rax, 0x2000004 ; put the write-system-call-code into register rax
mov rdi, 1 ; tell kernel to use stdout
mov rsi, query_string ; rsi is where the kernel expects to find the address of the message
mov rdx, query_string_len ; and rdx is where the kernel expects to find the length of the message
syscall
; read in the character
mov rax, 0x2000003 ; read system call
mov rdi, 0 ; stdin
mov rsi, in_char ; address for storage, declared in section .bss
mov rdx, 2 ; get 2 bytes from the kernel's buffer (one for the carriage return)
syscall
; show user the output
mov rax, 0x2000004 ; write system call
mov rdi, 1 ; stdout
mov rsi, out_string
mov rdx, out_string_len
syscall
mov rax, 0x2000004 ; write system call
mov rdi, 1 ; stdout
mov rsi, in_char
mov rdx, 2 ; the second byte is to apply the carriage return expected in the string
syscall
; exit system call
mov rax, 0x2000001 ; exit system call
xor rdi, rdi
syscall
section .data
vuid db "BC220425429", 0 ; Provided VUID: "BC220425429" numeric_array times 10 db 0 ; Array to store numeric digits largest_digit db 0 ; Variable to store the largest digit updated_array times 10 db 0 ; Array to store updated VUID temp_array times 10 db 0 ; Temporary array for sorting
section .text global _start
_start:
; Step 1: Store the numeric part of VUID in an array mov esi, vuid ; Point to the VUID string mov ecx, 10 ; Loop counter for 10 digits mov ebx, numeric_array ; Point to the numeric_array
extract_digits:
mov al, [esi] ; Load character from VUID cmp al, 0 ; Check if end of string je end_extract ; If end of string, exit loop
cmp al, '0' ; Check if character is a digit jl next_char ; If not a digit, skip to next character cmp al, '9' jg next_char
sub al, '0' ; Convert character to numeric value mov [ebx], al ; Store numeric value in array inc ebx ; Move to next element in array
next_char:
inc esi ; Move to next character in VUID loop extract_digits ; Repeat until all 10 digits are extracted
end_extract:
; Step 2: Find the largest numeric digit mov ebx, numeric_array ; Point to the numeric_array mov al, [ebx] ; Load the first digit mov [largest_digit], al ; Assume it as the largest digit
mov ecx, 9 ; Loop counter for remaining digits inc ebx ; Move to the next digit
compare_digits:
mov al, [ebx] ; Load the digit cmp al, [largest_digit] ; Compare with largest digit found so far jle skip_update ; If less than or equal, skip update mov [largest_digit], al ; Update largest digit
skip_update:
inc ebx ; Move to the next digit loop compare_digits ; Repeat until all digits are compared
; Step 3: Subtract each numeric digit from the largest digit mov ebx, numeric_array ; Point to the numeric_array mov edi, updated_array ; Point to the updated_array
subtract_digits:
mov al, [ebx] ; Load numeric digit sub al, [largest_digit] ; Subtract from largest digit mov [edi], al ; Store the result in updated_array inc ebx ; Move to the next digit inc edi ; Move to the next element in updated_array loop subtract_digits ; Repeat for all digits
; Step 4: Sort and store updated VUID in ascending order ; (You can implement any sorting algorithm here, like bubble sort or insertion sort)
; Sort updated_array using bubble sort mov ecx, 10 ; Number of elements dec ecx ; Outer loop counter
outer_loop:
mov ebx, updated_array ; Reset pointer to the beginning of the array mov edx, 9 ; Inner loop counter
inner_loop:
mov al, [ebx] ; Load current element mov ah, [ebx + 1] ; Load next element cmp al, ah ; Compare current and next element jg swap_elements ; If current element > next element, swap inc ebx ; Move to the next element dec edx ; Decrement inner loop counter jnz inner_loop ; Repeat inner loop until edx = 0 loop outer_loop ; Repeat outer loop until ecx = 0
; Store sorted array back to updated_array mov ebx, updated_array ; Point to the updated_array mov edi, temp_array ; Point to the temporary array for sorting mov ecx, 10 ; Loop counter rep movsb ; Copy the sorted array back to updated_array
; Display the sorted array mov eax, 4 ; Syscall number for sys_write mov ebx, 1 ; File descriptor (stdout) mov ecx, updated_array ; Pointer to the array mov edx, 10 ; Number of bytes to write int 0x80 ; Call kernel
; Exit the program mov eax, 1 ; Syscall number for sys_exit xor ebx, ebx ; Exit code 0 int 0x80 ; Call kernel
swap_elements:
; Swap elements in updated_array mov al, [ebx] ; Move current element to al mov ah, [ebx + 1] ; Move next element to ah mov [ebx], ah ; Move next element to current position mov [ebx + 1], al ; Move current element to next position jmp inner_loop ; Continue inner loop