1.11M Members

passing command line parameters mips

 
0
 

I have written a program that multiplies 2 decimals. My multiplication output is fine.

However I would like to do multiplication by passing in two parameters via command line. So far e.g. lets say if I just put '3 4' in the command line without the quotes.. nothing happens...

however if I put the numbers like this 'mult 3 4' -- of course without quote.. its works.. I see 12 on the console... is there anyway where I dont have to type in mult and just type '3 '4' ???

ideas???

 
0
 

code?

Are you trapping for a keyword mult?

How about trapping for operators

3 * 4
12
1 + 2
3
etc.

Or even
* 3 4
12

 
0
 

examples always help. thanks

 
0
 

meaning i can use an example..

 
0
 

Can't do that, you don't have code!

 
0
 

here is the code...

.data

errmsg:
	.asciiz "Two command line arguments required.\n"
newline:
	.asciiz "\n"
result:
	.space 11

.text
.globl main

main:
	move $s0, $a0
	move $s1, $a1
	move $s2, $zero
	move $s3, $zero
	move $s4, $zero

	# check if two arguments are given
	li $t0, 2
	ble $a0, $t0, error

	# parse the first number
	lw $a0, 4($s1)
	jal atoi
	move $s2, $v0

	# parse the second number
	lw $a0, 8($s1)
	jal atoi
	move $s3, $v0

	# multiply the numbers
	mult $s2, $s3
	mflo $s4

	# format the result
	la $a0, result
	move $a1, $s4
	jal itoa

	# print the result
	li $v0, 4
	la $a0, result
	syscall
	li $v0, 4
	la $a0, newline
	syscall

	b exit
error:
	# print error message
	li $v0, 4
	la $a0, errmsg
	syscall
exit:
	li $v0, 10
	li $a0, 0
	syscall

atoi:
	move $v0, $zero

	# detect sign
	li $t0, 1
	lbu $t1, 0($a0)
	bne $t1, 45, digit
	li $t0, -1
	addu $a0, $a0, 1
digit:
	# read character
	lbu $t1, 0($a0)

	# finish when non-digit encountered
	bltu $t1, 48, finish
	bgtu $t1, 57, finish

	# translate character into digit
	subu $t1, $t1, 48

	# multiply the accumulator by ten
	li $t2, 10
	mult $v0, $t2
	mflo $v0

	# add digit to the accumulator
	add $v0, $v0, $t1

	# next character
	addu $a0, $a0, 1
	b digit
finish:
	mult $v0, $t0
	mflo $v0
	jr $ra

itoa:
	subu $sp, $sp, 40
	sd $s0, 0($sp)
	sd $s2, 8($sp)
	sd $s4, 16($sp)
	sd $s6, 24($sp)
	sw $ra, 32($sp)

	move $s0, $a0
	move $s1, $a1

	# print minus if the number is negative
	bgez $s1, char
	li $t0, 45
	sb $t0, 0($s0)
	addu $s0, $s0, 1
	addu $a0, $a0, 1

	# make the number positive
	li $t0, -1
	mult $s1, $t0
	mflo $s1
char:
	# divide number by ten
	li $t0, 10
	divu $s1, $t0
	mflo $s1
	mfhi $t0

	# translate digit to character
	addu $t0, $t0, 48

	# write character
	sb $t0, 0($a0)

	# finish if quotient is zero
	beqz $s1, return

	# move to the next position
	addu $a0, $a0, 1
	b char
return:
	# put null character to the end of the string
	move $t0, $zero
	sb $t0, 1($a0)

	# reverse the string with the digits 
	move $a0, $s0
	jal reverse

	ld $s0, 0($sp)
	ld $s2, 8($sp)
	ld $s4, 16($sp)
	ld $s6, 24($sp)
	lw $ra, 32($sp)
	addu $sp, $sp, 40
	jr $ra

reverse:
	# find the last character in the string
	move $t0, $a0
next:
	lbu $t1, 0($t0)
	beqz $t1, last
	addu $t0, $t0, 1
	b next
last:
	# move to the last character
	subu $t0, $t0, 1
swap:
	# done when pointers meet
	bgeu $a0, $t0, done

	# exchange characters
	lbu $t2, 0($a0)
	lbu $t3, 0($t0)
	sb $t2, 0($t0)
	sb $t3, 0($a0)

	# step to the next pair
	addu $a0, $a0, 1
	subu $t0, $t0, 1
	b swap
done:
	jr $ra
 
0
 

here is the code...

.data

errmsg:
	.asciiz "Two command line arguments required.\n"
newline:
	.asciiz "\n"
result:
	.space 11

.text
.globl main

main:
	move $s0, $a0
	move $s1, $a1
	move $s2, $zero
	move $s3, $zero
	move $s4, $zero

	# check if two arguments are given
	li $t0, 2
	ble $a0, $t0, error

	# parse the first number
	lw $a0, 4($s1)
	jal atoi
	move $s2, $v0

	# parse the second number
	lw $a0, 8($s1)
	jal atoi
	move $s3, $v0

	# multiply the numbers
	mult $s2, $s3
	mflo $s4

	# format the result
	la $a0, result
	move $a1, $s4
	jal itoa

	# print the result
	li $v0, 4
	la $a0, result
	syscall
	li $v0, 4
	la $a0, newline
	syscall

	b exit
error:
	# print error message
	li $v0, 4
	la $a0, errmsg
	syscall
exit:
	li $v0, 10
	li $a0, 0
	syscall

atoi:
	move $v0, $zero

	# detect sign
	li $t0, 1
	lbu $t1, 0($a0)
	bne $t1, 45, digit
	li $t0, -1
	addu $a0, $a0, 1
digit:
	# read character
	lbu $t1, 0($a0)

	# finish when non-digit encountered
	bltu $t1, 48, finish
	bgtu $t1, 57, finish

	# translate character into digit
	subu $t1, $t1, 48

	# multiply the accumulator by ten
	li $t2, 10
	mult $v0, $t2
	mflo $v0

	# add digit to the accumulator
	add $v0, $v0, $t1

	# next character
	addu $a0, $a0, 1
	b digit
finish:
	mult $v0, $t0
	mflo $v0
	jr $ra

itoa:
	subu $sp, $sp, 40
	sd $s0, 0($sp)
	sd $s2, 8($sp)
	sd $s4, 16($sp)
	sd $s6, 24($sp)
	sw $ra, 32($sp)

	move $s0, $a0
	move $s1, $a1

	# print minus if the number is negative
	bgez $s1, char
	li $t0, 45
	sb $t0, 0($s0)
	addu $s0, $s0, 1
	addu $a0, $a0, 1

	# make the number positive
	li $t0, -1
	mult $s1, $t0
	mflo $s1
char:
	# divide number by ten
	li $t0, 10
	divu $s1, $t0
	mflo $s1
	mfhi $t0

	# translate digit to character
	addu $t0, $t0, 48

	# write character
	sb $t0, 0($a0)

	# finish if quotient is zero
	beqz $s1, return

	# move to the next position
	addu $a0, $a0, 1
	b char
return:
	# put null character to the end of the string
	move $t0, $zero
	sb $t0, 1($a0)

	# reverse the string with the digits 
	move $a0, $s0
	jal reverse

	ld $s0, 0($sp)
	ld $s2, 8($sp)
	ld $s4, 16($sp)
	ld $s6, 24($sp)
	lw $ra, 32($sp)
	addu $sp, $sp, 40
	jr $ra

reverse:
	# find the last character in the string
	move $t0, $a0
next:
	lbu $t1, 0($t0)
	beqz $t1, last
	addu $t0, $t0, 1
	b next
last:
	# move to the last character
	subu $t0, $t0, 1
swap:
	# done when pointers meet
	bgeu $a0, $t0, done

	# exchange characters
	lbu $t2, 0($a0)
	lbu $t3, 0($t0)
	sb $t2, 0($t0)
	sb $t3, 0($a0)

	# step to the next pair
	addu $a0, $a0, 1
	subu $t0, $t0, 1
	b swap
done:
	jr $ra
 
0
 

Command line Arguments are typically passed in one of two ways to a program at startup.

int count count of arguments
char *argv[] array of arguments

This seems to be the way you're handling it, and your code seems okay.
An alternate method is a single string where arguments have to be parsed but you aren't setup that way. You can be because your AtoI function tracks where the number ended and a non-digit continues.

This is assembly code, I am recommending much more commenting then you are doing!
For example:

#	_________________
#	ASCIIz to signed integer
#
#	(int) v0 = atoi( char * a0 )
	
atoi:
	move $v0, $zero
	
	 	# detect sign
	li $t0, 1
	lbu $t1, 0($a0)
	bne $t1, 45, digit		# (C <> '-')
	
		# NEGATIVE 
	li $t0, -1
	addu $a0, $a0, 1
	
digit:
		# read character
	lbu $t1, 0($a0)

	 	# finish when non-digit encountered
	bltu $t1, 48, finish	# (C < '0')
	bgtu $t1, 57, finish	# (C > '9')
	
	 	# translate character into digit
	subu $t1, $t1, 48		# C -= '0'
	
	 	# multiply the accumulator by ten
	li $t2, 10
	mult $v0, $t2
	mflo $v0				# v0 = Lo result
	
	 	# add digit to the accumulator
	add $v0, $v0, $t1		# N = (N * 10) + A
	
	 	# next character
	addu $a0, $a0, 1		# advance pointer
	b digit

		# handle sign
finish:
	mult $v0, $t0			# N *= { 1 : -1 }
	mflo $v0
	jr $ra
You
This article has been dead for over six months: Start a new discussion instead
Post:
Start New Discussion
Tags Related to this Article