I have the following code in MIPS that i run it in mars simulator The code open a text file for writing The problem with the result it keep printing all strings that i provide in My code without printing any new line i tried to separate new line from the string it did not work it keeping print space instead of new line Here is my code
.data
fout: .asciiz "testout.txt" # filename for output
buffer: .asciiz "The quick brown fox jumps over the lazy dog."
buffer1: .asciiz "\n"
.text
.globl main
main:
###############################################################
# Open (for writing) a file that does not exist
li $v0, 13 # system call for open file
la $a0, fout # output file name
li $a1, 1 # Open for writing (flags are 0: read, 1: write)
li $a2, 0 # modeA is ignored
syscall # open a file (file descriptor returned in $v0)
move $s6, $v0 # save the file descriptor
###############################################################
# Write to file just opened
li $v0, 15 # system call for write to file
move $a0, $s6 # file descriptor
la $a1, buffer # address of buffer from which to write
li $a2, 46 # hardcoded buffer length
syscall # write to file
###############################################################
# Write to file just opened
li $v0, 15 # system call for write to file
move $a0, $s6 # file descriptor
la $a1, buffer1 # address of buffer from which to write
li $a2, 1 # hardcoded buffer length
syscall # write to file
###############################################################
# Write to file just opened
li $v0, 15 # system call for write to file
move $a0, $s6 # file descriptor
la $a1, buffer # address of buffer from which to write
li $a2, 44 # hardcoded buffer length
syscall # write to file
###############################################################
# Close the file
li $v0, 16 # system call for close file
move $a0, $s6 # file descriptor to close
syscall # close
li $v0,10
syscall
Your base code was pretty much correct. And well commented! Good job.
The main issue was that you were hardwiring the string lengths.
In the first syscall for buffer
, the length was 46
[too high] and the file got an EOS char on the line. There was a newline output after that.
In the second syscall for buffer
, the length was 44
[too low] and the file line was chopped. There was no newline output after that because you didn't do a syscall for one.
So, the simple fix would be to just manually adjust the lengths, but I'd recommend a strlen
approach to output of text strings, just like you'd do in C.
I modified your code to add an fputs
function that has the strlen
as an internal loop [please pardon the gratuitous style cleanup]:
.data
fout: .asciiz "testout.txt" # filename for output
buffer: .asciiz "The quick brown fox jumps over the lazy dog."
nl: .asciiz "\n"
.text
.globl main
main:
###############################################################
# Open (for writing) a file that does not exist
li $v0,13 # system call for open file
la $a0,fout # output file name
li $a1,1 # Open for writing (flags are 0: read, 1: write)
li $a2,0 # modeA is ignored
syscall # open a file (file descriptor returned in $v0)
move $s6,$v0 # save the file descriptor
###############################################################
# Write to file just opened
# output string the first time
la $a1,buffer
jal fputs
# output newline
la $a1,nl
jal fputs
# output string the second time
la $a1,buffer
jal fputs
# output newline
la $a1,nl
jal fputs
###############################################################
# Close the file
li $v0,16 # system call for close file
move $a0,$s6 # file descriptor to close
syscall # close
li $v0,10
syscall
# fputs -- output string to file
#
# arguments:
# a1 -- buffer address
# s6 -- file descriptor
#
# registers:
# t0 -- current buffer char
# a2 -- buffer length
fputs:
move $a2,$a1 # get buffer address
fputs_loop:
lb $t0,0($a2) # get next character -- is it EOS?
addiu $a2,$a2,1 # pre-increment pointer
bnez $t0,fputs_loop # no, loop
subu $a2,$a2,$a1 # get strlen + 1
subiu $a2,$a2,1 # compensate for pre-increment
move $a0,$s6 # get file descriptor
li $v0,15 # syscall for write to file
syscall
jr $ra # return
UPDATE:
I used your code mars still exists there is no new line to be printed. mars ignores the new line and treat it as a null value.
I'm not sure what is happening on your end. I had tested this in mars
and the code is correct. Here is the hex dump of testout.txt
[which I had verified before posting]:
00000000: 54686520 71756963 6B206272 6F776E20 The quick brown
00000010: 666F7820 6A756D70 73206F76 65722074 fox jumps over t
00000020: 6865206C 617A7920 646F672E 0A546865 he lazy dog..The
00000030: 20717569 636B2062 726F776E 20666F78 quick brown fox
00000040: 206A756D 7073206F 76657220 74686520 jumps over the
00000050: 6C617A79 20646F67 2E0A lazy dog..
By contrast, the hex dump for your original code was:
00000000: 54686520 71756963 6B206272 6F776E20 The quick brown
00000010: 666F7820 6A756D70 73206F76 65722074 fox jumps over t
00000020: 6865206C 617A7920 646F672E 000A0A54 he lazy dog....T
00000030: 68652071 7569636B 2062726F 776E2066 he quick brown f
00000040: 6F78206A 756D7073 206F7665 72207468 ox jumps over th
00000050: 65206C61 7A792064 6F672E e lazy dog.
The only thing I can think of that might make a difference is the OS. I'm using linux. What is your OS? Windows? If so, the nl
might need to be:
nl: .asciiz "\r\n"
All other OSes should be fine.