Adds fopen(), fwrite(), fclose()

This commit is contained in:
2025-06-25 09:38:42 +02:00
parent 9d265e3db6
commit fbea8d0322
7 changed files with 181 additions and 9 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
*.lst
*.o
*.txt
tests

View File

@ -1,3 +1,4 @@
extern NR_write
extern strlen
section .rodata
@ -14,7 +15,7 @@ print:
call strlen
mov rdx, rax
mov rax, 1
mov rax, NR_write
mov rsi, rdi
mov rdi, 1
syscall
@ -30,7 +31,7 @@ puts:
mov r10, rdi
call print
mov rdi, r10
mov rax, 1
mov rax, NR_write
mov rdi, 1
mov rsi, NL
mov rdx, 1

View File

@ -1,6 +1,18 @@
section .rodata
global NR_read
global NR_write
global NR_open
global NR_close
global EOS
global NL
EOS equ 0x0
NL equ 0xA
;syscalls
NR_read equ 0
NR_write equ 1
NR_open equ 2
NR_close equ 3
;ascii
EOS equ 0x0
NL equ 0xA

110
file.asm Normal file
View File

@ -0,0 +1,110 @@
extern NR_read
extern NR_write
extern NR_open
extern NR_close
extern strlen
section .rodata
O_RDONLY equ 00000000q
O_WRONLY equ 00000001q
O_RDWR equ 00000002q
O_CREAT equ 00000100q
O_TRUNC equ 00001000q
O_APPEND equ 00002000q
section .text
global fopen
global fclose
global fwrite
;----- fopen(const char *filename, const char *mode) -----;
; return value: pointer to file or NULL if file failed to open
; ┌─────────────┬───────────────────────────────┐
; │fopen() mode │ open() flags │
; ├─────────────┼───────────────────────────────┤
; │ r │ O_RDONLY │
; ├─────────────┼───────────────────────────────┤
; │ w │ O_WRONLY | O_CREAT | O_TRUNC │
; ├─────────────┼───────────────────────────────┤
; │ a │ O_WRONLY | O_CREAT | O_APPEND │
; ├─────────────┼───────────────────────────────┤
; │ R │ O_RDWR │
; ├─────────────┼───────────────────────────────┤
; │ W │ O_RDWR | O_CREAT | O_TRUNC │
; ├─────────────┼───────────────────────────────┤
; │ A │ O_RDWR | O_CREAT | O_APPEND │
; └─────────────┴───────────────────────────────┘
fopen:
push rbp
mov rbp, rsp
cmp byte [rsi], 'r'
je .setMode_r
cmp byte [rsi], 'w'
je .setMode_w
cmp byte [rsi], 'a'
je .setMode_a
cmp byte [rsi], 'R'
je .setMode_R
cmp byte [rsi], 'W'
je .setMode_W
cmp byte [rsi], 'A'
je .setMode_A
xor rax, rax
jmp .quit
.setMode_r:
mov rsi, O_RDONLY
jmp .open
.setMode_w:
mov rsi, O_WRONLY | O_CREAT | O_TRUNC
jmp .open
.setMode_a:
mov rsi, O_WRONLY | O_CREAT | O_APPEND
jmp .open
.setMode_R:
mov rsi, O_RDWR
jmp .open
.setMode_W:
mov rsi, O_RDWR | O_CREAT | O_TRUNC
jmp .open
.setMode_A:
mov rsi, O_RDWR | O_CREAT | O_APPEND
jmp .open
.open:
mov rax, NR_open
syscall
.quit:
leave
ret
;----- fclose(FILE* fp) -----;
; return value: 0 on success, below 0 otherwise
fclose:
push rbp
mov rbp, rsp
mov rax, NR_close
syscall
leave
ret
;----- fwrite(FILE* fp, char* str) -----;
; writes a string to opened file
; return value: 0 on success, below 0 otherwise
fwrite:
push rbp
mov rbp, rsp
mov r9, rdi
mov rdi, rsi
call strlen
mov rdx, rax
mov rax, NR_write
mov rdi, r9
syscall
leave
ret

View File

@ -1,5 +1,5 @@
tests: tests.o constants.o core.o console.o string.o
gcc tests.o constants.o core.o console.o string.o -o tests -no-pie -z noexecstack
tests: tests.o constants.o core.o console.o string.o file.o
gcc tests.o constants.o core.o console.o string.o file.o -o tests -no-pie -z noexecstack
tests.o: tests.asm
nasm tests.asm -f elf64 -l tests.lst -g -F dwarf
constants.o: constants.asm
@ -10,6 +10,8 @@ console.o: console.asm
nasm console.asm -f elf64 -l console.lst -g -F dwarf
string.o: string.asm
nasm string.asm -f elf64 -l string.lst -g -F dwarf
file.o: file.asm
nasm file.asm -f elf64 -l file.lst -g -F dwarf
clean:
rm -f tests *.lst *.o
rm -f tests *.lst *.o testFile1.txt

View File

@ -44,8 +44,8 @@ strcpy:
.0f:
mov byte [r11], 0x0
cmp rcx, 0
je .quit
test rcx, rcx
jz .quit
mov rax, rdi
.quit:

View File

@ -23,6 +23,10 @@ extern strclr
extern strlclr
extern strcat
extern strcmp
;file.asm
extern fopen
extern fclose
extern fwrite
section .rodata
PRINT_nums equ 1
@ -42,6 +46,7 @@ section .rodata
TEST_tolower equ 1
TEST_toupper equ 1
TEST_strcmp equ 1
TEST_file1 equ 1
num1 dq 69
num2 dq 0xFFFFFF
@ -141,6 +146,16 @@ section .rodata
msgStrcmp4 db "TEST strcmp(str4, str1): %d",NL,EOS
msgStrcmp5 db "TEST strcmp(str1, str4): %d",NL,EOS
msgStrcmp6 db "TEST strcmp(str1, str1): %d",NL,EOS
; fopen(), fwrite(), fclose()
testFile1 db "testFile1.txt",EOS
fileStr1 db "Hello file world!",EOS
fileMode_w db "w",EOS
msgFileB db NL,"# fopen(), fwrite(), fclose()",EOS
msgFileB1 db "TEST fopen('testFile1.txt', 'w'): %d",NL,EOS
msgFileB2 db "TEST fwrite(filePointer1, fileStr1): %d",NL,EOS
msgFileB3 db "TEST fclose(filePointer1): %d",NL,EOS
section .data
filePointer1 dq 0
section .bss
strBuff1 resb 32
strBuff2 resb 8
@ -712,6 +727,37 @@ main:
lea rdi, [rel msgStrcmp6]
call printf
%ENDIF
%IF TEST_file1
lea rdi, [rel msgFileB]
call puts
; TEST: fopen()
lea rdi, [rel testFile1]
lea rsi, [rel fileMode_w]
call fopen
mov r15, rax ;store filepointer to R15
mov rsi, rax
xor rax, rax
lea rdi, [rel msgFileB1]
call printf
; TEST: fwrite()
mov rdi, r15
lea rsi, [fileStr1]
call fwrite
mov rsi, rax
xor rax, rax
lea rdi, [rel msgFileB2]
call printf
; TEST: fclose()
mov rdi, r15
call fclose
mov rsi, rax
xor rax, rax
lea rdi, [rel msgFileB3]
call printf
%ENDIF
leave
ret