Как я могу напечатать новую строку в текстовый файл в mips, просто напечатайте пробел

У меня есть следующий код в 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 

person hani94    schedule 30.05.2016    source источник


Ответы (1)


Ваш базовый код был в значительной степени правильным. И хорошо прокомментировал! Отличная работа.

Основная проблема заключалась в том, что вы жестко связывали длину строк.

В первом системном вызове для 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

ОБНОВЛЕНИЕ:

Я использовал ваш код, mars все еще существует, нет новой строки для печати. 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.

Единственное, что, как мне кажется, может иметь значение, это ОС. Я использую линукс. Какая у вас ОС? Окна? Если это так, nl может потребоваться:

nl:   .asciiz    "\r\n"

Все остальные ОС должны быть в порядке.

person Craig Estey    schedule 30.05.2016
comment
Я использовал ваш код mars все еще существует, нет новой строки для печати - person hani94; 30.05.2016
comment
mars игнорирует новую строку и рассматривает ее как нулевое значение - person hani94; 30.05.2016
comment
Проблема заключалась в том, что в ОС я использую Windows, и вы должны поставить \r перед \n, спасибо за вашу помощь. - person hani94; 31.05.2016
comment
Я полагал. Если бы это были окна, простые команды, такие как type или notepad, могли бы иметь проблемы с просто \n. IIRC, wordpad разберется. Утилиты Cygwin также будут работать. - person Craig Estey; 31.05.2016