Hello

My program is supposed to "remove" odd indices from a linked list (with the index starting from 1, and the last address of the linked list being 0):

The program should print out 13579, but it instead prints out 13268501024526850100872685009929.

I know assembly is tedious as hell, but I have been struggling with this for a while, so if there is any expert out there who can spot my error(s) quickly, that would be totally awesome.

In case it is not obvious, I am trying to translate the (working) C code into MIPS.

.data
X9: .word 9 0
X8: .word 8 X9
X7: .word 7 X8
X6: .word 6 X7
X5: .word 5 X6
X4: .word 4 X5
X3: .word 3 X4
X2: .word 2 X3
X1: .word 1 X2
X0: .word 0 X1

.text
main:

	la	$a0	X0
        move	$s0	$a0
        jal	remOdd
	move	$a0	$s0
        jal	print
        addiu	$v0	$zero	10
        syscall

remOdd:

# - - - - -
#
# C CODE:
#
# void remOdd( )
# {
#   if ( !list )
#     return ;
#	[... Continued below ]

# If !list -->> Branch to Done
	beq	$a0	$zero	Done

#
#   // Shift head
#   list = list->next ;
#   struct node* node = list ;
#
#	[... Continued below ]

	# SHIFT HEAD

	# a1 = X1 :: list->next
	lw	$a1	4($a0)
	beq	$a1	$zero	One

	# t1 = *X1 :: ( list->next )->value
	lw	$t1	0($a1)

	# X0: t1 X1
	sw	$t1	0($a0)

	# a2 = X2 :: ( list->next )->next
	lw	$a2	4($a1)
	beq	$a2	$zero	Two

	# a3 = X3 :: ( ( list->next )->next )->next
	lw	$a3	4($a2)

	# X0: t1 a3
	sw	$a3	4($a0)

#
#   // Relink
#   while ( node )
#     {
#       if ( !node->next )
# 	      return ;
#       
#       node->next = ( node->next )->next ;
#       node = node->next ;
#     }
#   
#   return ;
# }
#
# - - - - -

Loop:

#	node = a3

	# If !node -->> Branch to Done
	beq	$a3	$zero	Done

	# a2 = node->next
	lw	$a2	4($a3)

	# If !node->next --> Branch to Done
	beq	$a2	$zero	Done

	# t0 = ( node->next )->next
	lw	$t0	4($a2)

	# node->next = ( node->next )->next
	sw	$t0	0($a2)

	# node = node->next
	move	$a3	$t0

	j	Loop

One:
	sw	$zero	0($a0)
Two:
	sw	$zero	4($a0)
Done:
	jr	$ra
print:

	# t0 = Value to print
	lw	$t0	0($a0)

	# t1 = a0
	move	$t1	$a0

	# a0 = Value to print
	move	$a0	$t0

	# v0 = 1
	addiu	$v0	$zero	1

	# Print the value
        syscall

	# a0 = t1
	move	$a0	$t1

	# a0 = Next address
	lw	$a0	4($a0)

	# If the next address is not 0, continue printing
	bne	$a0	$zero	print

	# Jump to return address
	jr	$ra
# node->next = ( node->next )->next
	sw	$t0	0($a2)

I figured out the problem earlier today, and I thought to post back in case anybody was going to try to go through that madness to find the error. It turned out that changing the above line to "sw $t0 4($a3)" fixed it. I am not sure why it was originally wrong, but after spending so much time stepping through this code, I really don't care any more.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.