From 2c660ca7455e0bca382da32f0084e4e7545423c7 Mon Sep 17 00:00:00 2001 From: Perry Kivolowitz Date: Sun, 25 Dec 2022 15:37:29 -0600 Subject: [PATCH] lots of progress on file_ops - tired now --- section_1/funcs/file_ops.s | 131 +++++++++++++++++++++++++++---------- 1 file changed, 96 insertions(+), 35 deletions(-) diff --git a/section_1/funcs/file_ops.s b/section_1/funcs/file_ops.s index 2851c8d..280deda 100644 --- a/section_1/funcs/file_ops.s +++ b/section_1/funcs/file_ops.s @@ -19,71 +19,132 @@ fd .req w28 main: stp x29, x30, [sp, -16]! stp x27, x28, [sp, -16]! bl open_file - // w0 will contain either the file descriptor of the new - // file or -1 for a failure. Note that the value in w0 - // has also been copied to "fd" - a register alias. - cmp w0, wzr - bge 1f + // w0 will contain either the file descriptor of the new + // file or -1 for a failure. Note that the value in w0 + // has also been copied to "fd" - a register alias. + cmp w0, wzr + bge 1f // If we get here, the open has failed. Use perror() to // print a meaningful error and branch to exit. The return - // code of the program will be set to non-zero inside open_fail. - bl open_fail + // code of the program will be set to non-zero inside fail. + ldr x0, =fname + bl fail b 99f 1: // When we get here, the file is open. Write some data to it. - // If write_file returns non-zero, it signifies an error. If - // so, branch to the file closing code since the file is open. - // The error message will be printed in write_data. - bl write_data - cbnz w0, 10f + // If write_file returns non-zero, it signifies an error. If + // so, branch to the file closing code since the file is open + // after printing an error message. + bl write_data + cbz w0, 10f + // If we get here, there was an error in write_data. Print + // a reasonable error message then branch to the clean usleep + // code. + ldr x0, =wf // load legend + bl fail // print error + b 50f // branch to clean up. - // When we get here, we are done. Close the file. -10: mov w0, fd - bl close - mov retval, wzr + // Seek back to position zero preparing to read the file back. + // The return value in x0 (off_t) is the return value of + // lseek(). +10: bl seek_zero + cbz x0, 20f + // If we get here, the seek failed. Cause a reasonable + // message to be printed then branch to the clean up code. + ldr x0, =sf + bl fail + b 50f +20: + // When we get here, we are done. Close the file. +50: mov w0, fd + bl close + mov retval, wzr 99: ldp x27, x28, [sp], 16 ldp x29, x30, [sp], 16 mov w0, retval ret -/* This function attempts to open a file for both reading and - writing. Return values will be checked to ensure the file is - opened. If successful, 0 is returned (and the file descriptor - is squirreled away in register "fd". +/* open_file() + This function attempts to open a file for both reading and + writing. Return values will be checked to ensure the file is + opened. If successful, the fd is returned (and is squirreled + away in register "fd"). If unsuccessful, the -1 returned by + open() is passed back to the caller. + + Explanation of the magic numbers: + + int open(const char *pathname, int flags, mode_t mode); + octal 102 for flags is O_RDRW | O_CREAT + octal 600 for mode is rw------- i.e. read and write for + the owner but no permissions for anyone else. */ + .equ O_FLAGS, 0102 + .equ O_MODE, 0600 + open_file: - stp x29, x30, [sp, -16]! - ldr x0, =fname - mov w1, 0102 - mov w2, 0600 - bl open - mov fd, w0 - ldp x29, x30, [sp], 16 - ret + stp x29, x30, [sp, -16]! + ldr x0, =fname + mov w1, O_FLAGS + mov w2, O_MODE + bl open + mov fd, w0 + ldp x29, x30, [sp], 16 + ret /* This function uses perror to print a meaningful error - message in the event of an open failure. + message in the event of a failure. The string value + passed to perror arrives to us as a pointer in x0. */ -open_fail: +fail: stp x29, x30, [sp, -16]! - ldr x0, =fname - bl perror - mov retval, 1 + bl perror + mov retval, 1 ldp x29, x30, [sp], 16 ret +/* ssize_t write(int fd, const void *buf, size_t count); +*/ + write_data: stp x29, x30, [sp, -16]! + str x20, [sp, -16]! + mov w0, fd // file descriptor + ldr x1, =txt // address to print from + ldr x2, =txt_s // load pointer to size + ldr x2, [x2] // dereference the pointer + mov w20, w2 // need this value for error check. + bl write + cmp x0, x20 // Did we write the expected amount? + bne 90f + // successful write - return 0 + mov x0, xzr + b 99f +90: // failure - ensure we return non-zero! + mov x0, 1 +99: ldr x20, [sp], 16 ldp x29, x30, [sp], 16 ret - .data +/* off_t lseek(int fd, off_t offset, int whence); +*/ +seek_zero: + stp x29, x30, [sp, -16]! + mov w0, fd // file descriptor + mov x1, xzr // beginning of file + mov w2, wzr // SEEK_SET - absolute offset + bl lseek + ldp x29, x30, [sp], 16 + ret + + .data prog: .asciz "file_ops" +wf: .asciz "write failed" +sf: .asciz "lseek failed" fname: .asciz "test.txt" txt: .asciz "some data\n" txt_s: .word txt_s - txt - 1 // strlen(txt) - .end + .end