Learning MIPS assembly: read text and write to file

1

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 
assembly
mips
asked on Stack Overflow Feb 15, 2013 by webrama.pl • edited Feb 15, 2013 by Jim Mischel

1 Answer

1

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').

answered on Stack Overflow Apr 27, 2013 by tigerjack89 • edited Mar 15, 2019 by Winter

User contributions licensed under CC BY-SA 3.0