Skip to content

Instantly share code, notes, and snippets.

@Chriscbr
Created July 14, 2024 03:35
Show Gist options
  • Save Chriscbr/3eab2db84a165e92be087b9bf4f414c0 to your computer and use it in GitHub Desktop.
Save Chriscbr/3eab2db84a165e92be087b9bf4f414c0 to your computer and use it in GitHub Desktop.
Prints numbers from a file - written in NASM
; nasm -fmacho64 numbers.asm && gcc numbers.o -o numbers && ./numbers
global _main
extern _printf
extern _scanf
extern _fopen
extern _fgets
extern _atoi
section .text
_main:
push rbx ; Call stack must be aligned
lea rdi, [rel prompt] ; First argument is address of prompt
call _printf ; printf(message)
lea rdi, [rel scanFormat] ; First argument is address of scanFormat
lea rsi, [rel fileName] ; Second argument is address of fileName
call _scanf ; scanf(scanFormat, fileName)
lea rdi, [rel fileName] ; First argument is address of fileName
lea rsi, [rel readOpenMode] ; Second argument is address of readOpenMode
call _fopen ; fopen(fileName, readOpenMode)
mov r12, rax ; Save file handle in r12
cmp r12, 0 ; Did fopen return NULL?
je _fileError ; If so, jump to _fileError
mov r13, 0 ; Initialize counter
lea r14, [rel numberData] ; Holds address of next numberData element to write
_readLoop:
lea rdi, [rel line] ; First argument is address of line
mov rsi, lineSize ; Second argument is sizeof line
mov rdx, r12 ; Third argument is file handle
call _fgets ; fgets(line, r12)
cmp rax, 0 ; Did fgets return NULL?
je _echo ; If so, jump to _done
lea rdi, [rel line] ; First argument is address of line
call _atoi ; atoi(line)
mov dword [r14], eax ; Write atoi result to numberData
inc r13 ; Increment counter
add r14, 4 ; Advance pointer to next numberData element
cmp r13, dataSize ; Compare counter to dataSize
jl _readLoop ; If counter is less than dataSize, jump to _readLoop
jmp _echo ; Otherwise, jump to _echo
_fileError:
lea rdi, [rel fileErrorMsg] ; First argument is address of fileErrorMsg
call _printf ; printf(message)
mov rax, 0x02000001 ; system call for exit
xor rdi, 1; exit code 1
syscall ; invoke operating system to exit
_echo:
mov dword [r14], maxInt ; set last entry of numberData to maxInt, the sentinel value
lea r14, [rel numberData] ; Reset pointer to numberData
_echoLoop:
cmp dword [r14], maxInt ; Did we reach the sentinel value?
je _done ; If so, jump to _done
lea rdi, [rel printNumFormat] ; First argument is address of printNumFormat
mov rsi, [r14] ; Second argument is the numberData value
call _printf ; printf(printNumFormat, number)
add r14, 4 ; Advance pointer to next numberData element
jmp _echoLoop ; Jump to _echoLoop
_done:
lea rdi, [rel done] ; First argument is address of done
call _printf ; printf(done)
pop rbx ; Fix up stack before returning
ret
section .data
prompt: db "Enter the name of the file to read: ", 0
done: db "Done.", 10, 0
scanFormat: db "%99s", 0
printNumFormat: db "%d", 10, 0
readOpenMode: db "r", 0
fileErrorMsg: db "Error opening file.", 10, 0
maxInt equ 0xFFFFFFFF
section .bss
fileNameSize equ 100
fileName: resb fileNameSize
maxNumbers equ 1000
dataSize equ 1000
numberData: resd dataSize
lineSize equ 20
line: resb lineSize
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment