Search code examples
assemblymipsnewlinemars-simulator

How i can print a new line to a text file in mips it just print a space


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 

Solution

  • 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.