mirror of
https://github.com/pkivolowitz/asm_book.git
synced 2026-06-22 03:46:46 +08:00
lots of progress on file_ops - tired now
This commit is contained in:
parent
10bbbab3a1
commit
2c660ca745
1 changed files with 96 additions and 35 deletions
|
|
@ -19,71 +19,132 @@ fd .req w28
|
||||||
main: stp x29, x30, [sp, -16]!
|
main: stp x29, x30, [sp, -16]!
|
||||||
stp x27, x28, [sp, -16]!
|
stp x27, x28, [sp, -16]!
|
||||||
bl open_file
|
bl open_file
|
||||||
// w0 will contain either the file descriptor of the new
|
// w0 will contain either the file descriptor of the new
|
||||||
// file or -1 for a failure. Note that the value in w0
|
// file or -1 for a failure. Note that the value in w0
|
||||||
// has also been copied to "fd" - a register alias.
|
// has also been copied to "fd" - a register alias.
|
||||||
cmp w0, wzr
|
cmp w0, wzr
|
||||||
bge 1f
|
bge 1f
|
||||||
// If we get here, the open has failed. Use perror() to
|
// If we get here, the open has failed. Use perror() to
|
||||||
// print a meaningful error and branch to exit. The return
|
// print a meaningful error and branch to exit. The return
|
||||||
// code of the program will be set to non-zero inside open_fail.
|
// code of the program will be set to non-zero inside fail.
|
||||||
bl open_fail
|
ldr x0, =fname
|
||||||
|
bl fail
|
||||||
b 99f
|
b 99f
|
||||||
|
|
||||||
1: // When we get here, the file is open. Write some data to it.
|
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
|
// If write_file returns non-zero, it signifies an error. If
|
||||||
// so, branch to the file closing code since the file is open.
|
// so, branch to the file closing code since the file is open
|
||||||
// The error message will be printed in write_data.
|
// after printing an error message.
|
||||||
bl write_data
|
bl write_data
|
||||||
cbnz w0, 10f
|
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.
|
// Seek back to position zero preparing to read the file back.
|
||||||
10: mov w0, fd
|
// The return value in x0 (off_t) is the return value of
|
||||||
bl close
|
// lseek().
|
||||||
mov retval, wzr
|
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
|
99: ldp x27, x28, [sp], 16
|
||||||
ldp x29, x30, [sp], 16
|
ldp x29, x30, [sp], 16
|
||||||
mov w0, retval
|
mov w0, retval
|
||||||
ret
|
ret
|
||||||
|
|
||||||
/* This function attempts to open a file for both reading and
|
/* open_file()
|
||||||
writing. Return values will be checked to ensure the file is
|
This function attempts to open a file for both reading and
|
||||||
opened. If successful, 0 is returned (and the file descriptor
|
writing. Return values will be checked to ensure the file is
|
||||||
is squirreled away in register "fd".
|
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:
|
open_file:
|
||||||
stp x29, x30, [sp, -16]!
|
stp x29, x30, [sp, -16]!
|
||||||
ldr x0, =fname
|
ldr x0, =fname
|
||||||
mov w1, 0102
|
mov w1, O_FLAGS
|
||||||
mov w2, 0600
|
mov w2, O_MODE
|
||||||
bl open
|
bl open
|
||||||
mov fd, w0
|
mov fd, w0
|
||||||
ldp x29, x30, [sp], 16
|
ldp x29, x30, [sp], 16
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
/* This function uses perror to print a meaningful error
|
/* 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]!
|
stp x29, x30, [sp, -16]!
|
||||||
ldr x0, =fname
|
bl perror
|
||||||
bl perror
|
mov retval, 1
|
||||||
mov retval, 1
|
|
||||||
ldp x29, x30, [sp], 16
|
ldp x29, x30, [sp], 16
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
/* ssize_t write(int fd, const void *buf, size_t count);
|
||||||
|
*/
|
||||||
|
|
||||||
write_data:
|
write_data:
|
||||||
stp x29, x30, [sp, -16]!
|
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
|
ldp x29, x30, [sp], 16
|
||||||
ret
|
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"
|
prog: .asciz "file_ops"
|
||||||
|
wf: .asciz "write failed"
|
||||||
|
sf: .asciz "lseek failed"
|
||||||
fname: .asciz "test.txt"
|
fname: .asciz "test.txt"
|
||||||
txt: .asciz "some data\n"
|
txt: .asciz "some data\n"
|
||||||
txt_s: .word txt_s - txt - 1 // strlen(txt)
|
txt_s: .word txt_s - txt - 1 // strlen(txt)
|
||||||
.end
|
.end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue