我如何在 mips 中将新行打印到文本文件它只打印 space

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

我在 MIPS 中有以下代码,我 运行 它在火星模拟器中 代码打开一个文本文件进行写入 结果的问题是它不断打印我提供的所有字符串 我的代码没有打印任何新行我试图将新行与字符串分开它不起作用它保持打印space而不是新行 这是我的代码

.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 

您的基本代码非常正确。而且好评!干得好。

主要问题是您硬连接了字符串长度。

buffer 的第一个系统调用中,长度为 46 [太长],文件在该行上有一个 EOS 字符。在那之后一个换行符输出。

buffer 的第二个系统调用中,长度为 44 [太短],文件行被截断。在那之后 没有 换行符输出,因为你没有为一个系统调用。

因此,简单的解决方法是手动调整长度,但我建议使用 strlen 方法来输出文本字符串,就像您在 C 中所做的那样。

我修改了您的代码以添加一个 fputs 函数,该函数将 strlen 作为内部循环 [请原谅无偿样式清理]:

    .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

更新:

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.

我不确定你这边发生了什么。我在 mars 中对此进行了测试,代码是正确的。这是 testout.txt 的十六进制转储 [我在发布前已经验证]:

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

相比之下,原始代码的十六进制转储是:

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.

我能想到的唯一可能有所不同的是 OS。我正在使用 linux。你的 OS 是什么? Windows?如果是这样,nl 可能需要是:

nl:   .asciiz    "\r\n"

所有其他 OSes 应该没问题。