How to read file in MIPS - file

I have the following file, and I'd like to be able to read the file into 2 buffers in MIPS, but only after an offset of 4 chars and I'm just wondering how I'd do that, I tried having two reads where I store abc d in buffer1 and another read call where I store "def ghi jkl mno" but that didn't work
abc def ghi jkl mno
Here's the code, if someone can tell me how to correctly manipulate the pointer to the contents of the file, that would be appreciated
# Open (for reading) a file
li $v0, 13 # system call for open file
la $a0, filename # output file name
li $a1, 0 # flags
syscall # open a file (file descriptor returned in $v0)
move $t0, $v0 # save file descriptor in $t0
# Read to file just opened
li $v0, 14 # system call for read to file
la $a1, buffer1 # address of buffer from which to write
li $a2, 4 # hardcoded buffer length
move $a0, $t0 # put the file descriptor in $a0
syscall # write to file
li $v0, 14 # system call for read to file
la $a1, buffer # address of buffer from which to write
li $a2, 15 # hardcoded buffer length
move $a0, $t0 # put the file descriptor in $a0
syscall

Related

How can we accessing array data in MIPS

i have a problems in MIPS, i read a line in file then split the string to an array of integer values , finally i get an array with those number 100,5,20,-8,2. i want to print the value a[4]=2 to a file.I read a link that give me an instruction about how we can access the value 2 at position 4 http://people.cs.pitt.edu/~xujie/cs447/AccessingArray.htm . i try my code
output: .asciiz "output.txt"
#open file
li $v0, 13
la $a0,output
li $a1, 1
li $a2, 0
#accessing array
la $t3,buffer //access my array name buffer
li $t5,4 //$t5=4
add $t5,$t5,$t5
add $t5,$t5,$t5
add $t1,$t5,$t3
//write to file
li $v0, 15
move $a0, $s6
move $a1, $t1
li $a2, 4 //buffer length
syscall
//close
li $v0, 16
move $a0, $s6
syscall
But when i check my file ,nothing happend in my file. What happended ? Thanks for your help

Understanding opening and reading a file in assembly

I've got a project for a class in which we have to transform a picture using sobel operators in assembly, and I'm having a bit of a problem understanding some example code.
In the data segment and in the main function is everything that's need to make the function work (The code works, I just don't understand why).
The bit I don't understand is the use of the li command to change the values of the $aregisters.
read_rgb_image:
# Place file and size in register,
move $s0, $a0 #file name
move $s1, $a1 #buffer
move $s2, $a2 #buffersize
# Open file
move $a0, $s0 # File's directory/name
li $a1, 0 #THIS LI ARE THE COMMANDS I DON'T UNDERSTAND
li $a2, 0 # Read life
li $v0, 13 # Option for opening file
syscall
# Read file
move $a0, $v0 # File descriptor
move $a1, $s1 # Buffer with result
move $a2, $s2 # Space of information to read
li $v0, 14 # Read file
syscall
# Store read buffer
move $s1, $v0
# Close file
li $v0, 16 # Close file
syscall
# Return
move $v0, $s1 # Make return
jr $ra
nop
Can somebody please explain this to me?!
The LI instruction loads an numeric value into a register. Before you make a system call, you need to load the $v0 register with the number assigned to the system service. You also need to load argument registers with system service specific parameters. Without the documentation, we can only guess (beyond the comments in the code) why the specific values being loaded into the registers. However, that is what is going on.
We can guess that you are calling the 4-paremeter version of the open function and that your specifing the file name, mode=0, and flags=0 using the argument registers.
MIPS defines pseudoinstructions that are not actually part
of the instruction set but are commonly used by programmers and compilers.
load immediate li is a pseudoinstruction it loads a 32-bit constant using a combination of lui and ori instructions.
The following instructions are equivalent.
MIPS instruction
lui $s0, 0x1234
ori $s0, 0xAA77
pseudoinstruction
li $s0, 0x1234AA77

Reading and Printing User Entered MIPS Array

So I am using MIPS trying to read in several strings entered by a user and then print them, but I am not getting the behavior I expect.
I want to take in 4 bytes of user input (4 characters essentially). In my loop I use the letter 'D' as a signal to exit. The problem is, no matter what I input, when I try to print the very first input later (or even the second, or the third), all I get printed out is the letter 'D' that was used to exit (which should be the last value of the array no?).
.data
mem: .space 256 #256 bytes of space for input
inst .space 5
.text
la $s1, mem #s1 used to take input
la $s2, 0($s1) #Pointer to base address of memory
jal readLoop #Read input loop
lw $a0, 0($s2) #Attempt to read very first saved input
li $v0, 4
syscall
li $v0, 10 #End program
syscall
readLoop:
li $v0, 8 #read string
la $a0, inst #location of input memory
addi $a1, $zero, 5 #length of buffer
syscall
lb $t2,($a0) #used to exit loop
sw $a0, 0($s1) #store input into memory
addi $s1, $s1, 4 #increment memory by 4 bytes
li $t1, 'D'
bne $t2, $t1, readLoop #exit loop on input of a 'D'
jr $ra
I've checked my input as it comes in and even when in the array after saving. It seems my print is the problem, but I could easily be wrong. Any ideas?
The fix was rather easy. Instead of storing the user input into a separate memory location and then putting that location in my array, I simply had the user input be stored directly into my array. See code changes below.
.data
mem: .space 256 #256 bytes of space for input
.text
la $s1, mem #s1 used to take input
jal readLoop #Read input loop
la $a0, mem #Attempt to read very first saved input
li $v0, 4
syscall
li $v0, 10 #End program
syscall
readLoop:
li $v0, 8 #read string
la $a0, mem #set user input as memory location
addi $a1, $zero, 5 #length of buffer
syscall
lb $t2,($a0) #used to exit loop
addi $s1, $s1, 4 #increment memory by 4 bytes
li $t1, 'D'
bne $t2, $t1, readLoop #exit loop on input of a 'D'
jr $ra

Read File into an Array? - MIPS

I'm not sure exactly how to tackle this, but I need to code a function that takes in an address for the start of an array, address of a file name, and the maximum number for bytes to read. I'm not even sure if my code works or not, but this is what I have, I just don't think this is reading in the values into an array form. If someone can clarify what exactly syscall 14 does, i'd appreciate it.
fill_the_array:
la $t0, 0($a0) #base address of the array in memory
la $t1, 0($a1) #address of the filename in memory
move $t2, $a2 # maximum number of bytes to read from the file into memory
#open file
li $v0, 13 #syscall for opening the file
la $a0, 0($t1) #address of file name
li $a1, 0 #read in data
li $a2, 0 #mode is ignored
syscall #open the file descriptor
move $s0, $v0 # file descriptor
move $a0, $s0 # file descriptor
move $a1, $t0 #address into input buffer (the address for the array???)
move $a2, $t2 # maximum number of bytes
li $v0, 14
syscall
#close the file
li $v0, 16
move $a0, $s0
syscall
jr $ra
If someone can clarify what exactly syscall 14 does, i'd appreciate it.
Name Number Arguments Returns
--------------------------------------------------------------------------------------------------------------------------------------
read from file 14 $a0 = file descriptor $v0 contains number of characters read (0 if end-of-file, negative if error).
$a1 = address of input buffer
$a2 = maximum number of characters to read
So it reads a number of bytes (at most $a2 bytes) from a file, and stores them in memory starting at the address given in $a1. The actual number of bytes read is then returned in $v0.
If you need to check whether or not your code works, run it in a simulator like MARS or SPIM. They both have memory viewers. They also let you single-step through your code and set breakpoints, in case your code isn't working as expected and you need to find out where things go wrong.

Create and write to file on MIPS

I'm trying to create a file named "exit.txt", and write some data on it. I have tried different flags and modes, but that doesn't seem to work. This is the code I'm using:
str_exit: .asciiz "/home/LinuxPc/Desktop/exit.txt"
file_write:
li $v0, 13
la $a0, str_exit
li $a1, 1
la $a2, 0
syscall
Is there any way to make it work ??
Thanks !!
In addition to the answer of gusbro (open file stream before writing) it might help to set the flags and mode for the open file call as follows:
li $a1, 0x41
li $a2, 0x1FF
This sets the flag to the hex value 0x41 which tells the call to first create the file. While the mode is set to hex value 0x1FF which is converted to the binary value
0000 0000 0001 1111 1111 that sets the file permission for:
(...)0 111(n) 111(g) 111(others).
You put the code to open a file in write mode, but you didn't write anything into the file.
Here goes an example of how to open/write/close a file:
.data
str_exit: .asciiz "test.txt"
str_data: .asciiz "This is a test!"
str_data_end:
.text
file_open:
li $v0, 13
la $a0, str_exit
li $a1, 1
li $a2, 0
syscall # File descriptor gets returned in $v0
file_write:
move $a0, $v0 # Syscall 15 requieres file descriptor in $a0
li $v0, 15
la $a1, str_data
la $a2, str_data_end
la $a3, str_data
subu $a2, $a2, $a3 # computes the length of the string, this is really a constant
syscall
file_close:
li $v0, 16 # $a0 already has the file descriptor
syscall

Resources