Created
July 14, 2024 03:35
-
-
Save Chriscbr/3eab2db84a165e92be087b9bf4f414c0 to your computer and use it in GitHub Desktop.
Prints numbers from a file - written in NASM
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; 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