MIPS: is it possible to overwrite certain words of a file? - mips

Is it possible to overwrite a file using MIPS?
I have a file and, under certain conditions (i.e. a user decide to update his personal data or delete completely) I need to delete/overwrite some words or row of the text file I have.
I tried this thing:
I already know how to find which word I would like to replace and, with a store byte i write on a buffer the "new" word.
Then I should save it on file. And that's where my problems begin since, using flag 1 (on syscall 13) overwrites the whole file and flag 9 doesn't apply any change. Here's my code. What am I doing wrong?
loop:
la $t6, empty_space
sb $t6, buffer($s7)
beq $s7, $t5, save_on_file
subi $s7, $s7, 1
j loop
save_on_file:
#open file
li $v0, 13
la $a0, file_out
li $a1, 1
li $a2, 0
syscall
move $s6, $v0
#write on file
li $v0, 15
move $a0, $s6
la $a1, buffer
move $a2, $s7
syscall
#close
li $v0, 16
move $a0, $s6
syscall
j menu

Related

MIPS Assembly File Writing

I am trying to write to a file in MIPS assembly and it seems that I cannot get it to work. The code is straightforward, but the $v0 register returns -1 no matter what I type. I have tried other people's code and still end up getting the same results.
The code:
filename: .asciiz "file.txt"
buffer: .asciiz "hello textual world"
.text
open_file:
li $v0, 13 # open file
la $a0, filename # file name
li $a1, 1 # write flag
li $a2, 0 # ignore mode
syscall
jal print
write_to_file:
move $a0, $v0 # descriptor
li $v0, 15 # write to file
la $a1, buffer # buffer
li $a2, 20 # max chars to write
syscall
jal print
close_file:
li $v0, 16 # close
# move $a0, $v0 # descriptor
syscall
jal print
li $v0, 10 # exit program
syscall
print:
move $a0, $v0
li $v0, 1
syscall # print v0
li $v0, 11
li $a0, '\n'
syscall # print '\n'
jr $ra
The output:
-1
-1
16
-- program is finished running --
A Screenshot of the Mars dir. Note: I know that the dir contains "FILES.txt" rather than the "file.txt" one. However, I am trying to create a new file.
EDIT:
After some time I ran the program and solved the issue. For some reason, the first syscall did not return -1 when I ran it today, but the problem was that in "jal print", $v0 changed its value, which means that the line that follows it, first line of write_to_file label, loads an incorrect descriptor to $a0. Another potential problem is that I put 20 characters to print instead of 19.
Long story short, I've saved the file descriptor in $s0 and put 19 characters to be written and now the program works.

MIPS - My loop doesn't perform quite how it should

I am trying to construct a while loop in Mars MIPS assembly however I have run into a bit of a problem, where the loop itself works, however the action of halving the number with each pass of the loop doesn't seem to initiate after the first round.
Below is the loop I have:
div:
sra $s0, $t1, 1 #halves the number in $s0
li $v0, 1
add $a0, $zero, $s0 #Prints out the number in $s0
syscall
li $a0, 32
li $v0, 11 #Prints out a space
syscall
loop:
blt $s0, $s4, exit #Loops to the start of div until it reaches 1
j div
exit:
li $v0, 10 #This is the exit.
syscall
All help is welcome, as I have a terrible feeling a rookie mistake is being made here.

MIPS, how to invert a series of numbers in a while loop (a rapid method)

I coding an exercise but I have find a little problem... My exercise ask me that convert a character (keyboard input) in:
ASCII code
Binary code
Hex code
without the MIPS syscall. 2 points on 3 are solved for now but in the point 2 I have find my problem... When I insert a letter for example, the binary code is invertited (see below)
Give me a character: a
ASCII: 97
Binary 10000110 (The real is 01100001)
Exist an easy method to invert this number? I leave the code below.
print_binary:
#move the function parameter in t0
move $t0, $a0
#Show a message
li $v0, 4
la $a0, m3
syscall
while:
#check if my counter is 8(conversion on 8 bit)
beq $t2, 8, end_loop
#Divide the number
div $t1, $t0, 2
#move hi in t4 to show in video
mfhi $t4
#Counter
add $t2, $t2, 1
#move for another division
move $t0, $t1
#Show hi for every division
li $v0, 1
move $a0, $t4
syscall
j while
end_loop:
jr $ra
I don't use the array very well, so I would avoid this method if possible...
Thank you

In MIPS, how to use syscall 14 to read through a long file?

I am currently working on a project (using MARS) where I need to read a multi-line file using syscall 14. I have a set buffer-length that I am using for the syscall that is 80-bytes long. I have set up my loop within a _readLine function so that the contents of the buffer should be printed to the console with each iteration. This is how I realized that my loop only reads the first 80-bytes of a file, and nothing more.
I've been scouring the internet trying to find a hint on why I can't read the next 80-bytes of the file. I thought it might have something to do with the file descriptor, but when I tried incrementing it, nothing changed, and it was still only outputting the first 80-bytes of the file with syscall 14.
Can someone please help me figure out what is wrong, or give me an idea as how to point to the next 80 bytes of my file? My code is below (fileBuff holds the address of a user-inputted file name, and _printBuffer is a function I use later in my program but you can ignore).
main:
# Open file for reading
addi $v0, $zero, 13
la $a0, fileBuff
add $a1, $zero, $zero # pass in flags
add $a2, $zero, $zero # pass in mode
syscall # open a file (file descriptor returned in $v0)
add $s6, $zero, $v0 # store descriptor in $a0
jal _readLine # call _readFile function
jal _printBuffer
addi $v0, $zero, 10 # prepare to exit the program
syscall # exit
_readLine:
readLoop:
add $a0, $zero, $s6 # setup file descriptor
la $a1, buffer # address of buffer
addi $a2, $zero, 80 # read 80 bytes
addi $v0, $zero, 14 # read from the file (descriptor already in $a0, buffer address in $a1, buffer length in $a2)
syscall # write to the file
beq $v0, $zero, doneReading
slt $t0, $v0, $zero # if end of file, then close file
beq $t0, 1, doneReading # if error, then close file
la $t0, buffer # load buffer address into $t0
add $s6, $zero, $v0 # save file length in $s0
add $s6, $s6, $t0 # change descriptor to where last left off in the file
#### remove... eventually
addi $v0, $zero, 4
la $a0, buffer
syscall
####
j readLoop
doneReading:
addi $v0, $zero, 16 # syscall to close the file
add $a0, $zero, $s6 # file descriptor to close
syscall # close the file
jr $ra
Syscall 14 reads in a continuous string.
When you tell it to read 80-bytes, it will read 80 bytes.
When you call it again (without closing it), it will read the next 80 bytes and so on.
So I suggest you move this block of code:
addi $v0, $zero, 16 # syscall to close the file
add $a0, $zero, $s6 # file descriptor to close
syscall # close the file
into your main block right before the system exit call.

MIPS Beq Add/Subtract Switch

I am new to MIPS trying to figure out Branches and Switches. All I want to do is set switch 0 to add and switch 1 to subtract. Can someone help and explain what I am doing wrong because every video I watch does not help. Every time I run the program I previously had, all it did was run the add: switch over and over again.
li $a0, 2
li $a1, 1
main:
li $s0, 0xf0100000
li $s1, 0b00000001
li $s2, 0b00000010
start:
lw $t0, 0($s0)
beq <------ This is what I don't understand
nop
add:
addu $v0, $a0, $a1
j start
nop
subtract:
subu $v0, $a0, $a1
j start
nop