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