How to create a file using user input with assembl

2019-08-12 09:27发布

I'm trying to record in a file an user input, using assembly.

I'm working with this code but when the file is created, the input isn't recorded on the file correctly. Someone can help me with this? Here is my code:

.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 

1条回答
三岁会撩人
2楼-- · 2019-08-12 09:52

Your user input call did not setup the pointer to buffer. So, it would read into prompt instead. Also, the given length was 454 instead of the [intended] 45. Further, this syscall does not return a length, so saving v0 did nothing.

After fixing the above the program works. But, it would write a fixed length output so there were binary zeroes at the end.

I've added some code to calculate the string length (e.g. like strlen). I've also added sidebar comments to most lines. I highly recommend this for any asm. Anyway, here's the corrected program [please pardon the gratuitous style cleanup]:

    .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
查看更多
登录 后发表回答