Как создать файл с использованием пользовательского ввода с помощью сборки

Я пытаюсь записать в файл пользовательский ввод, используя сборку.

Я работаю с этим кодом, но когда файл создается, ввод не записывается в файл правильно. Кто-нибудь может мне с этим помочь? Вот мой код:

.data

file1: .asciiz "file1.txt"
prompt: .asciiz "User entry\n"
buffer: .space 45

.text   

    la $a0,prompt
    li $v0,4
    syscall

    li $v0, 8
    li $a1, 454
    syscall
    move $s1, $v0
    j writeFile1

writeFile1: 
            li $v0, 13
            la $a0, file1
            li $a1, 1
            li $a2, 0
            syscall
            move $s6, $v0

            #write
            li $v0, 15
            move $a0, $s6
            la $a1, buffer 
            li $a2, 45
        syscall

        #close
        li $v0, 16
            move $a0, $s6
            syscall
            j exit



exit:   li  $v0, 10
        syscall 

person Thiago Almeida Marques    schedule 10.03.2016    source источник
comment
Определите ввод неверно записан в файл.   -  person Michael    schedule 10.03.2016
comment
например, когда вход является тестовым, выходной файл будет следующим: 4675 6e63 696f 6e6f 7520 6120 6573 6372 6974 6120 6e6f 2041 7271 7569 766f 2032 2e00 0000 0000 0000 0000 0000 00   -  person Thiago Almeida Marques    schedule 10.03.2016
comment
Что ж, то, как вы используете syscall 8, не имеет особого смысла. См. документацию для правильного использования.   -  person Michael    schedule 11.03.2016


Ответы (1)


Ваш вызов пользовательского ввода не установил указатель на buffer. Таким образом, вместо этого будет прочитано prompt. Кроме того, заданная длина была 454 вместо [предполагаемой] 45. Кроме того, этот системный вызов не возвращает длину, поэтому сохранение v0 ничего не дало.

После исправления вышесказанного программа работает. Но он будет записывать выходные данные фиксированной длины, поэтому в конце будут двоичные нули.

Я добавил код для вычисления длины строки (например, strlen). Я также добавил комментарии на боковой панели к большинству строк. Я очень рекомендую это для любого ассемблера. В любом случае, вот исправленная программа [извините за бесплатную очистку стиля]:

    .data

file1:      .asciiz     "file1.txt"
prompt:     .asciiz     "User entry\n"
buffer:     .space      46
    .eqv    BUFMAX      45              # usable buffer length (one less)

    .text

    # prompt user
    la      $a0,prompt                  # prompt string
    li      $v0,4                       # puts syscall number
    syscall

    # read user string
    li      $v0,8
    la      $a0,buffer                  # FIXME -- this was missing
    li      $a1,BUFMAX                  # FIXME -- this was 454
    syscall
    ###move $s1,$v0                     # FIXME -- does nothing v0 is not length

    ###li       $s1,BUFMAX              # use fixed length
    ###j        writeFile1              # would do write with zeroes in file

    # calculate string length (e.g. like strlen)
    move    $s1,$a0                     # point to buffer start
getlen:
    lb      $t0,0($s1)                  # get byte -- is it zero?
    addi    $s1,$s1,1                   # advance pointer
    bne     $t0,$zero,getlen            # no, loop
    sub     $s1,$s1,$a0                 # get length from end pointer
    subi    $s1,$s1,1                   # compensate for preincrement

writeFile1:
    # open the output file
    li      $v0,13                      # open syscall number
    la      $a0,file1                   # filename
    li      $a1,1                       # open for writing
    li      $a2,0                       # open mode
    syscall
    move    $s6,$v0                     # save fildes number

    # write
    li      $v0,15                      # write syscall number
    move    $a0,$s6                     # get fildes number
    la      $a1,buffer                  # get buffer pointer
    move    $a2,$s1                     # get buffer length
    syscall

    # close
    li      $v0,16
    move    $a0,$s6                     # get fildes number
    syscall
    j       exit

exit:
    li      $v0,10                      # exit syscall number
    syscall
person Craig Estey    schedule 11.03.2016