I'm trying to write simple program in MIPS assembly language. What i'm trying to do is read multiple characters from keyboard and save its to file. I'm creating file with 13 opcode and saving characters with 15 opcode. I don't understand: how to dynamically assign number of characters to write in $a2 for 15 opcode (line 37, now hardcoded). Also I can't figure out how to print numbers of characters written to my file ($v0 contains this value after writting to file, line 49).
Now program is throwing error: line 49: Runtime exception at 0x00400078: address out of range 0x0000002c
Here is my code:
.data
handle_text:
.space 100 # buffor of 100 characters, bits, bytes?
out_file:
.asciiz "file_out.txt" # out file
asklabel:
.asciiz "\Please enter string to save\n"
countlabel:
.asciiz "\Characters typed:\n"
.text
main:
la $a0, asklabel # text to print
li $v0, 4 # opcode
syscall
la $a0, handle_text # Where to put text
la $a1, handle_text # Number of characters to write
li $v0, 8 # opcode
syscall
li $v0, 13 # system call for open file
la $a0, out_file # output file name
li $a1, 1 # Open for writing (flags are 0: read, 1: write)
li $a2, 0 # mode is ignored
syscall # open a file (file descriptor returned in $v0)
move $s6, $v0 # save the file descriptor
move $a0, $s6 # file handle
la $a1, handle_text # text to print
#line 37
li $a2, 44 # TEXT LENGTH
li $v0, 15 # opcode
syscall
move $t1, $v0 # move v0 to t1 so v0 won't be overwritten
la $a0, countlabel # show text
li $v0, 4 # op code
syscall
move $a0, $t1 # place characters amount in $a0
li $v0, 4 # opcode
syscall
# ERROR. Maybe it's becouse string should be null terminated?
li $v0, 16 # system call for close file
move $a0, $s6 # file descriptor to close
syscall # close file
li $v0, 10 # close app
syscall
First of all
# buffor of 100 characters, bits, bytes?
They are bytes, not bits. Also, the string
la $a1, handle_text
at line 21 is completely wrong, cause you have to load a number, not an address. You can use for example
.data
length: .word 100
[...]
lw $a1, length
Also, get in mind that you can effectively read only 99 characters, cause the last has to be a '/0'
.
At line 37, you still can use
lw $a2, length
instead of the hardcoded 44.
About this
# ERROR. Maybe it's because string should be null terminated?
No, it's because you want to print a string, while $t1=$v0 is an integer. To print the number of read characters, you have to call the syscall 1 (not 4).
To answer your question, it's not very simple to pass an ordinary number to the argument, because you have to set a maximum number one way or another. For example, in this way, your output is always 100, even if you type in 10 characters. The simplest way to solve this is with a "loop", something like
li $t0, -1
loop:
addi $t0, $t0, 1
lw $t1, handle_text($t0)
bnez $t1, loop
addi $t0, $t0, -1
At the end of the code, $t0 contains the exact number of characters (excluding '\0'
and '\n'
).
User contributions licensed under CC BY-SA 3.0