Skip to content

Read ecall always returns 4 characters, GetCWD returns "4", ecall_file.s test fails #383

@Alexandre425

Description

@Alexandre425

Hi, I am having a variety of issues with the system calls when attempting to read a file.

.equ FILE_RDONLY    0x00
.equ FILE_WRONLY    0x01
.equ FILE_RDWR      0x02

.equ ECALL_Exit     10
.equ ECALL_Close    57
.equ ECALL_Read     63
.equ ECALL_Open     1024

.equ BUFFER_SIZE    1024

.data
file_path: .string "C:\Users\<redacted>\image.txt"
buffer: .zero BUFFER_SIZE
str_buffer: .zero BUFFER_SIZE

.text
    j       main


# draws the image in 'buffer' on the LED matrix
# a0: the image size, in bytes
draw_image:
    # ...

main:
    la      a0, str_buffer
    li      a1, BUFFER_SIZE
    li      a7, 17 # GetCWD
    ecall

    la      a0, str_buffer
    li      a7, 4 # PrintString
    ecall

    # Open the input file
    la      a0, file_path   # argument 0: pointer to the file path string
    li      a1, FILE_RDONLY # argument 1: file flags
    li      a7, ECALL_Open  # ecall code for Open
    ecall                   # open the file (return the file descriptor)
    mv      s0, a0          # move the file descriptor somehere safe

    # Read the contents into the buffer
    # a0 already contains the file descriptor, which is incidentally the first argument
    la      a1, buffer      # argument 1: pointer to the buffer
    li      a2, BUFFER_SIZE # argument 2: maximum number of bytes to read
    li      a7, ECALL_Read  # ecall code for Open
    ecall
    mv      s1, a0          # move the size somewhere safe

    # Close the input file
    mv      a0, s0          # argument 0: the file descriptor
    li      a7, ECALL_Close
    ecall

    mv      a0, s1  # argument 0: the image size (bytes)
    call draw_image

    j       exit

exit:
    li      a7 ECALL_Exit
    ecall

I have redacted the file path, but I can assure you it matches the absolute path of a file on my computer, in my main drive, in which Ripes is installed as well.

Firstly, the GetCWD followed by the PrintString ecalls prints "4" to the console, which is unexpected. I discovered this will trying to use relative file paths, which did not resolve the issues detailed below.

image

Secondly, no matter the path in file_path, the Open ecall never fails, and always returns a file descriptor of 3. If the file does not exist, Ripes will create it, even though the O_CREATE flag is not set. I based my flags on the following:

# File open modes
O_RDONLY: .word 0x0000
O_WRONLY: .word 0x0001
O_RDWR: .word 0x0002
O_ACCMODE: .word 0x0003
# Additional file flags
O_CREAT: .word 0x0100
O_EXCL: .word 0x0200
O_TRUNC: .word 0x1000
O_APPEND: .word 0x2000

Whether the file path points to a file that exists or not, the Read always returns a value of 4 in a0, even though the buffer (1024 bytes) and the file (620 bytes) are much larger.

image
image

Following the Read, the buffer's memory location will contain 0xffffffff, which does not correspond to the file contents.

Given the odd behavior, I imagine I am working with some incorrect assumptions. I tried running the the ecall tests, but the following line contains what I assume is a mistake, which prevents the code from assembling:

sw t1, 0(s2), t0 # Store to buffer

Removing the t0 from the end of said line allows it to compile. However, running this test, despite the fact the file is created in Ripes' directory, the ecall to Write fails.

lw a7, WRITE # a7: "Write" ecall
ecall # Returns to a0: Number of bytes written
bne a0, s1, fail # Ensure write returned correct number of bytes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions