Hey guys, I wrote a program that reads a file and then displays its 8, 16 and 32 bit checksum as well as the XOR values. I've managed to do it and it works fine under windows(using qtspim) but on centos(using mars) I get the following errors:
Line 7 column five: "li": too many or incorrectly formatted operands. Expected li $t1, -100
Line 94 column 23: "$t0" : operand is of incorrect type
Line 97 column 23: "0xfffffffc" : operand is of incorrect type
Line 289 column 23: "$t1": operand is of incorrect type
I need to get it working in mars.I'd be grateful for your help.
and below source code: ( I marked the error lines on the left )
my code:
.text
main:
# extend data segment
li $v0, 9 # sbrk syscall
7 - li $a0, 500000+4 # the the maximum data size (a multiple of 4) plus an extra word
syscall
bnez $v0, store
li $v0, 4 # print error string
la $a0, memory_error
syscall
b exit
store:
sw $v0, buffer # store the file buffer address
# get input file name from user
get_filename:
li $v0, 4 # print prompt for input file
la $a0, prompt
syscall
li $v0, 8 # read input filename
la $a0, filename
li $a1, 100
syscall
# search for \n and replace it with terminating 0
li $t1, -1 # filename length (will be determined in the following loop)
search:
lb $t0, 0($a0)
add $a0, $a0, 1
add $t1, $t1, 1
bne $t0, 0x0a, search
sb $zero, -1($a0)
beqz $t1, exit # exit if no filename was given
# open and read the file
li $v0, 13 # open file syscall
la $a0, filename
li $a1, 0 # flags
li $a2, 0 # mode (ignored)
syscall
bgez $v0, read_file
li $v0, 4 # print error string
la $a0, open_error
syscall
b exit
read_file:
sw $v0, descriptor
li $v0, 14 # read from file syscall
lw $a0, descriptor # the file descriptor
lw $a1, buffer
li $a2, 500000 # max number of bytes to read
syscall
bgez $v0, process
li $v0, 4 # print error string
la $a0, read_error
syscall
b exit
process:
srl $s0, $v0, 1 # number of halfwords
and $t0, $v0, 0x1
beqz $t0, number_of_words
add $s0, $s0, 1 # round up (i.e. add 1) if the data size is not a multiple of 2
number_of_words:
srl $s1, $v0, 2 # number of words
and $t0, $v0, 0x3 # the remainder from division by 4 (number of effective data bytes in the last word)
beqz $t0, pad
add $s1, $s1, 1 # round up
# pad the data with 0s
pad:
li $t1, 4
sub $t0, $t1, $t0 # 4 minus the above remainder (specifies how many bytes to zero in a bit mask)
sll $t0, $t0, 3 # multiply by 8 to determine the number of zero bits to insert from the right
li $t1, 0xffffffff # initial value of the mask
94- srl $t1, $t1, $t0 # insert zero bits and form actual bit mask (note: little endian order)
add $t2, $a1, $v0 # the address of the end of the data
97- and $t2, $t2, 0xfffffffc # the address (divisible by 4) that will be affected by the bit mask
lw $t0, ($t2) # load the word that will contain the padding 0 bytes, note: this step can access (but not change) a whole extra word after the data when its size is a multiple of 4
and $t0, $t0, $t1 # zero the unused bytes (using the bit mask)
sw $t0, ($t2) # store it
# modular sum
# 8-bit checksum
move $t0, $v0 # number of bytes of the data (a counter)
move $t1, $a1 # the start address of the data
li $s2, 0 # clear the "accumulator"
sum8:
lbu $t2, ($t1)
add $t1, $t1, 1
addu $s2, $s2, $t2
sub $t0, $t0, 1
bnez $t0, sum8
sll $s2, $s2, 24 # sign extend byte to word (first align the sign bit of the byte to make use of arithmetic shifting)
sra $s2, $s2, 24 # insert the sign bit between bits 31-8
# 16-bit checksum
move $t0, $s0
move $t1, $a1
li $s3, 0
sum16:
lhu $t2, ($t1)
add $t1, $t1, 2
addu $s3, $s3, $t2
sub $t0, $t0, 1
bnez $t0, sum16
sll $s3, $s3, 16 # sign extend halfword to word
sra $s3, $s3, 16
# 32-bit checksum
move $t0, $s1
move $t1, $a1
li $s4, 0
sum32:
lw $t2, ($t1)
add $t1, $t1, 4
addu $s4, $s4, $t2
sub $t0, $t0, 1
bnez $t0, sum32
# parity check
# 8-bit XOR value
move $t0, $v0
move $t1, $a1
li $s5, 0
xor8:
lbu $t2, ($t1)
add $t1, $t1, 1
xor $s5, $s5, $t2
sub $t0, $t0, 1
bnez $t0, xor8
# 16-bit XOR value
move $t0, $s0
move $t1, $a1
li $s6, 0
xor16:
lhu $t2, ($t1)
add $t1, $t1, 2
xor $s6, $s6, $t2
sub $t0, $t0, 1
bnez $t0, xor16
# 32-bit XOR value
move $t0, $s1
move $t1, $a1
li $s7, 0
xor32:
lw $t2, ($t1)
add $t1, $t1, 4
xor $s7, $s7, $t2
sub $t0, $t0, 1
bnez $t0, xor32
# report results to the user
# 8-bit checksum
li $v0, 4 # print string
la $a0, checksum8
syscall
li $v0, 1 # print int
move $a0, $s2
syscall
li $v0, 4 # print string
la $a0, new_line
syscall
# 16-bit checksum
li $v0, 4 # print string
la $a0, checksum16
syscall
li $v0, 1 # print int
move $a0, $s3
syscall
li $v0, 4 # print string
la $a0, new_line
syscall
# 32-bit checksum
li $v0, 4 # print string
la $a0, checksum32
syscall
li $v0, 1 # print int
move $a0, $s4
syscall
li $v0, 4 # print string
la $a0, new_line
syscall
# 8-bit XOR value
li $v0, 4 # print string
la $a0, xor_value8
syscall
move $a0, $s5 # the number to print
li $a1, 6 # start digit offset (6 implies a byte)
jal print_hex
# 16-bit XOR value
li $v0, 4 # print string
la $a0, xor_value16
syscall
move $a0, $s6 # the number to print
li $a1, 4 # type: halfword
jal print_hex
# 32-bit XOR value
li $v0, 4 # print string
la $a0, xor_value32
syscall
move $a0, $s7 # the number to print
li $a1, 0 # type: word
jal print_hex
close:
li $v0, 16 # close file syscall
lw $a0, descriptor # the file descriptor
syscall
b get_filename # loop to process another file (or exit)
# exit the program
exit:
li $v0, 10
syscall
# subroutine to print hexadecimal number
# $a0 => number to print
# $a1 => start digit: 0=word, 4=halfword, 6=byte
print_hex:
la $t0, hex # address to store the string representation of a hexadecimal number
li $t1, 28 # shift count (to the right) of the most significant hexadecimal digit
hex_loop:
289 srl $t2, $a0, $t1 # get a value of a hexadecimal digit
and $t2, $t2, 0xf # mask unused bits
bgtu $t2, 9, letter
add $t2, $t2, 0x30 # a digit 0-9, add 0x30 to get actual ASCII code
b next_hex
letter:
add $t2, $t2, 0x57 # a letter a-f, add ('a'-10) to get actual ASCII code
next_hex:
sb $t2, ($t0) # store the digit
add $t0, $t0, 1 # advance the pointer
sub $t1, $t1, 4 # update the shift count (to get another digit)
bgez $t1, hex_loop
li $v0, 4 # print string
la $a0, hex_prefix
syscall
li $v0, 4 # print string
la $a0, hex
add $a0, $a0, $a1
syscall
jr $ra
.data
filename: .space 16 # input filename
descriptor: .word 0 # input file descriptor
buffer: .word 0 # input file buffer address
prompt: .asciiz "\nEnter the file name: "
memory_error: .asciiz "Memory error (sbrk syscall failed)\n"
open_error: .asciiz "Cannot open file\n"
read_error: .asciiz "Cannot read file\n"
checksum8: .asciiz "8-bit checksum: "
checksum16: .asciiz "16-bit checksum: "
checksum32: .asciiz "32-bit checksum: "
xor_value8: .asciiz "8-bit XOR value: "
xor_value16: .asciiz "16-bit XOR value: "
xor_value32: .asciiz "32-bit XOR value: "
new_line: .asciiz "\n"
hex_prefix: .asciiz "0x"
hex: .asciiz "????????\n"