【问题标题】:How i can print a new line to a text file in mips it just print a space我如何在 mips 中将新行打印到文本文件中它只是打印一个空格
【发布时间】:2016-09-28 05:01:03
【问题描述】:

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

.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 

【问题讨论】:

    标签: assembly mips newline mars-simulator


    【解决方案1】:

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

    主要问题是你硬连线了字符串长度。

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

    buffer 的第二个系统调用中,长度为44 [太低] 并且文件行被截断。之后有 no 换行输出,因为您没有为其中一个进行系统调用。

    因此,简单的解决方法是手动调整长度,但我建议使用 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
    

    更新:

    我使用了你的代码,火星仍然存在,没有要打印的新行。 mars 忽略新行并将其视为空值。

    我不确定你那边发生了什么。我在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.
    

    我能想到的唯一可能会有所不同的是操作系统。我正在使用Linux。你的操作系统是什么?视窗?如果是这样,nl 可能需要:

    nl:   .asciiz    "\r\n"
    

    所有其他操作系统都应该没问题。

    【讨论】:

    • 我用了你的代码,火星仍然存在,没有新行要打印
    • mars 忽略新行并将其视为空值
    • 问题是因为我使用的操作系统是windows,你应该把\r放在\n之前,谢谢你的帮助
    • 我想通了。如果是 Windows,typenotepad 之类的简单命令可能无法使用 just \n。 IIRC,wordpad 会弄清楚的。 Cygwin 实用程序也可以使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-13
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多