#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2010
    Posts
    1
    Rep Power
    0

    Unhappy MIPS sentence in a linked list


    I'm trying to store the characters of a string into a linked list. I created the linked list I'm having trouble storing the characters in the linked list. I know to get a character in a string you use load byte, but my linked list a series of .word format.

    I was wondering how to go about storing the characters in the linked list. Here's my code so far. Thanks.

    Code:
    li $a0, 100
    li $v0, 9
    syscall
    add $a0, $0, $v0
    li $a1, 100
    li $v0, 8
    syscall
    move $t0, $a0
    add $t3, $0, $t0
    
    lb $t1, 0($t0)
    bgtz $t1, count
    b no_string
    
    count:
    add $s0, $s0, 1
    add $t0, $t0, 1
    lb $t1, 0($t0)
    bgtz $t1, count
    beqz $t1, done_count
    sub $t0, $t0, $s0
    
    done_count: 
    add $a0, $0, $s0
    li $v0, 1
    syscall 
    b mem_init
    
    
    mem_init:
    # create the first node 
            li      $v0,9             # allocate memory
            li      $a0,8             # 8 bytes
            syscall                   # $v0 <-- address
            move    $s1,$v0           # $s1 = &(first node)
            
            # copy the pointer to first
            sw      $s1,FreeList
            
            # initialize the first node
            lb $t4, 0($t3)             # store 1
            sw $t4,0($s1)        # at displacement 0
    
            # create the remaining nodes in a counting loop
            li      $s2,2             # counter = 2
    	  add $t3, $t3, 1
            add $s3, $0, $s0             # upper limit
            
    loop:   bgtu    $s2,$s3,done      # while (counter <= limit )
            
            # create a node 
            li      $v0,9             # allocate memory
            li      $a0,8             # 8 bytes
            syscall                   # $v0 <-- address
            
            # link this node to the previous
                                      # $s1 = &(previous node)
            sw      $v0,4($s1)        # copy address of the new node
                                      # into the previous node
            
            # make the new node the current node
            move    $s1,$v0
            
            # initialize the node
    	  lb $t4, 0($t3)
    	  sw $t4,0($s1)        # at displacement 0        
            addi $s2,$s2,1         # counter++
    	  add $t0, $t0, 1
            b       loop
            
    done:
            # end the list
            sw      $0,4($s1)         # put null in the link field
                                      # of the current node, which
                                      # is the last node.
  2. #2
  3. Commie Mutant Traitor
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Jun 2004
    Location
    Alpharetta, GA
    Posts
    1,806
    Rep Power
    1570
    Here's the thing in assembly: there aren't really any data types that are enforced by the system. It doesn't really matter that the data is 'declared' as one size or not; you can still use the operations of the other sizes on all or parts of it, so long as the operations are valid and do what you want them to. You can treat a 4-byte integer as a 4-character string at one point, or as half of an 8-byte FP number somewhere else, if that does what you need it to. You rarely want to mix and match that way, but the point is, the assembler doesn't care.

    That having been said, in order to have the strings as part of your linked list, you'd need a) a place to put the string data, either a set buffer or as something dynamically allocated, and b) a pointer to the first byte of that location. That does seem to be what your doing, so that should work correctly.

    This is something I wrote up some time back to explain just how to work with structures in MIPS assembly (running under the SPIM emulator specifically, which seems to be what you're using) which you may find Illuminating fnord. Keep in mind that the structures exist more in your mind than in the program, so careful pointer discipline is even more important than in most higher-level languages - if you aren't careful, you could not only mis-set a pointer, but you could unintentionally use the wrong stored value as if it were a pointer, sending your program spinning out of control.

    BTW, you might want to give symbolic names to the different system call IDs, as it would make parts of the code more readable:
    Code:
    print_int 	= 1 	 	
    print_float 	= 2 	
    print_double    = 3  	
    print_string    = 4 	
    read_int 	= 5 
    read_float 	= 6 
    read_double     = 7 
    read_string     = 8 
    malloc          = 9 
    exit 	        = 10 		
    print_character = 11 	
    read_character 	= 12 
    open_file       = 13 
    read_file       = 14
    write_file      = 15
    close_file      = 16
    exit2           = 17
    If you put these equates at the top of the program, you would then be able to use the names of the syscalls instead of just some magic number:

    Code:
        li $a0, 100
        li $v0, malloc
        syscall
        add $a0, $0, $v0
        li $a1, 100
        li $v0, read_string 
        syscall
    You still should comment the code more, too; it took me a bit to figure out that this snippet is allocating a 100-byte buffer for your strings. With something as complicated as a even a simple linked list, comments are a must in assembly, even for a lot of things that would seem obvious in a HLL.

    Finally, I noticed that you seem to be doing a relative unconditional branch to the mem_init procedure, instead of a procedure call (usually done with 'jal', jump and link, which stores the return address in $ra; the return uses 'jr', jump register, which jumps to the location pointed to by the register given - which is usually $ra). That's going to cause a problem because, well, the procedure needs to return at some point, doesn't it? Or am I reading your code wrong?
    Last edited by Schol-R-LEA; May 9th, 2010 at 04:33 PM.
    Rev First Speaker Schol-R-LEA;2 JAM LCF ELF KoR KCO BiWM TGIF
    #define KINSEY (rand() % 7) λ Scheme is the Red Pill
    Scheme in Short Understanding the C/C++ Preprocessor
    Taming Python A Highly Opinionated Review of Programming Languages for the Novice, v1.1

    FOR SALE: One ShapeSystem 2300 CMD, extensively modified for human use. Includes s/w for anthro, transgender, sex-appeal enhance, & Gillian Anderson and Jason D. Poit clone forms. Some wear. $4500 obo. tverres@et.ins.gov
  4. #3
  5. Commie Mutant Traitor
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Jun 2004
    Location
    Alpharetta, GA
    Posts
    1,806
    Rep Power
    1570
    You might also find using the following stack offset constants helpful in maintaining function call stack discipline:
    Code:
    #stack offsets
    fp.ra = 4
    fp.a0 = 8
    fp.a1 = 12
    fp.a2 = 16
    fp.a3 = 20
    fp.s0 = -4
    fp.s1 = -8
    fp.s2 = -12
    When you start a function which itself makes function calls, it may be necessary to save certain registers on the stack. You usually want to do this as early as possible, even given how much slower memory access would be on a real machine than register access. A typical stack frame setup might look like this:
    Code:
    	addi	$sp, $sp, -20
    	sw	$fp, 8($sp)
    	addi	$fp, $sp, 8	# set the stack ptr between the args 
    				# and the locals
    	sw	$a0, fp.a0($fp)
    	sw	$ra, fp.ra($fp)
    	sw	$s0, fp.s0($fp)
    Here, the function is setting aside a 20-byte stack frame following the MIPS calling conventions, in order to save the five registers $sp, $fp, $ra, $a0 and $s0.
    Rev First Speaker Schol-R-LEA;2 JAM LCF ELF KoR KCO BiWM TGIF
    #define KINSEY (rand() % 7) λ Scheme is the Red Pill
    Scheme in Short Understanding the C/C++ Preprocessor
    Taming Python A Highly Opinionated Review of Programming Languages for the Novice, v1.1

    FOR SALE: One ShapeSystem 2300 CMD, extensively modified for human use. Includes s/w for anthro, transgender, sex-appeal enhance, & Gillian Anderson and Jason D. Poit clone forms. Some wear. $4500 obo. tverres@et.ins.gov

IMN logo majestic logo threadwatch logo seochat tools logo