Thread: Need help with Mips

  1. #1
    Stressed Student :(
    Join Date
    Feb 2008
    Location
    Berkeley, CA
    Posts
    73

    Need help with Mips

    I can't seem to figure this out, the bug in this swap procedure in C is the *temp is a pointer to a pointer, and I seem to have written the wrong version of it in Mips. I have two problems, one, I don't know what is wrong with this swap procedure, and two, I don't know how to properly write it in Mips. Any suggestions guys?

    Code:
    Problem:
    void swap (int *px, int *py) {
        int *temp;
        *temp = *px;
        *px = *py;
        *py = *temp;
    }
    
    Correct swap:
    void swap (int *px, int *py) {
        int temp;
        temp = *px;
        *px = *py;
        *py = temp;
    }
    This is my buggy version of swap, which unfortunately, isn't buggy. The directions in my lab said that "cannot use $t0 to hold temp." So how do I write this?

    My attempt:
    Code:
    swap:	
    	addi $sp, $sp, -8
    	sw 	 $ra, 4($sp)
    	sw	 $s0, 0($sp)
    	lw	 $t0, 0($a1)
    	addi $t3, $v0, 0    #ptr *temp
    	add	 $s0, $t0, 0 	#i'm so lost lol
    	move $a0, $a1
    	move $a1, $s0
    	lw	 $s0, 0($sp)
    	lw	 $ra, 4($sp)
    	addi $sp, $sp, 8
    	jr	 $ra

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Is "move" a macro? As far as I can see, MIPS doesn't have a move instruction...

    The reason your "buggy" version isn't failing is probably that the compiler optimizes the memory access for temp into a temporary register location, never actually modifying the location given by temp itself.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Stressed Student :(
    Join Date
    Feb 2008
    Location
    Berkeley, CA
    Posts
    73
    I quite don't understand, can you give an example?
    I'm assuming it is in the move macro, because I've tried to write sw $s0, 0($a1), and I would get a different answer.

    I don't understand though, why int *temp; and int temp are different in MIPS since pointers and integers are both 4 bytes each, I don't see why the compiler should notice it. Maybe it's the value of *temp which is the memory address... Maybe that sw idea that I tried earlier might be right. Any more suggestions?

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> I don't understand though, why int *temp; and int temp are different...
    They may both be 4 bytes, but you are not using them the same.

    >>*temp = *px;
    This dereferences temp.

    gg

  5. #5
    uint64_t...think positive xuftugulus's Avatar
    Join Date
    Feb 2008
    Location
    Pacem
    Posts
    355
    Do you have a push instruction available for the processor? It will come in handy to avoid using any register...
    Code:
    ...
        goto johny_walker_red_label;
    johny_walker_blue_label: exit(-149$);
    johny_walker_red_label : exit( -22$);
    A typical example of ...cheap programming practices.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by xuftugulus View Post
    Do you have a push instruction available for the processor? It will come in handy to avoid using any register...
    No, mips doesn't appear to have a push instruction, which is why the epilog and prolog parts use sw/lw relative to sp to perform push/pop-like instructions.

    @NoobieGecko: There is a BIG difference between int *temp and int temp - one of them represents a memory location that you can store an integer in, the other represents a memory location that should contain another memory location that can hold an integer. Since the temp pointer is uninitialized, it also doesn't point to anything in particular, and thus when you try to access that memory, an undefined behaviour occurs. Depending on various things, the possible results of this undefined behaviour includes (but not a comprehensive list):
    - that it writes a memory location used by something else.
    This is particularly bad, as it can lead to very hard to find bugs.
    - that it tries to write to a unavailable part of memory
    Good - you catch the error immediately.
    - it writes to a valid but unused memory location
    Very bad, because later on, at a point when you think this code is OK, you get a #1 or #2 happening, and the bug hunt is going to be really hard.
    - that little green men appear at your desk.
    Unlikely, but we are talking undefined behaviour.

    Undefined behaviour is like driving (or walking) across a "red light" on a road-crossing. The outcome is not always the same, it could be (again, not a complete list):
    1. You get across to the other side unharmed, all is well.
    2. You get across, but the police sees you and you get a ticket.
    3. You get hit by a car/bus/truck going the other direction - your car is damaged but you don't get hurt yourself.
    4. You get hit by a car/bus/truck going the other direction - you get hurt.
    5. You get hit by ... and a space-ship from a foreign universe beams you up and you end up unharmed.

    The best plan is to NOT run red lights, because that's where things have a defined behaviour [as long as no one else runs the red lights[1]]

    [1] This is where "the rest of your code needs to behave too".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Stressed Student :(
    Join Date
    Feb 2008
    Location
    Berkeley, CA
    Posts
    73
    Okay cool, I get what you guys are saying, it totally makes sense. What I also mean is, when you write int *temp; and int temp; in mips, I don't know the difference of the syntax. You still push the stack 4 blocks down (4 bytes) for a register and you still pass it a value: lw $s0 0($a0). So if I rewrite the code, do I have to use "move"? I think what I said earlier could be right.

    xtuft, the mips code is what i'm running on mars, it's a simulator -- so no processor

  8. #8
    uint64_t...think positive xuftugulus's Avatar
    Join Date
    Feb 2008
    Location
    Pacem
    Posts
    355
    I don't know the syntax of your simulated machine.
    But for x86 to write an int from register the assembly code is:
    Code:
    MOV MEM, REG
    eg.
    MOV 0x15000000, EAX
    To write an int from a pointer in a register
    Code:
    MOV WORD PTR [REG], REG
    eg.
    MOV WORD PTR [EDI], EAX
    And they clearly are quite different as you see. The first uses an immediate address for the instruction while the second uses the content of a register as an address for the instruction.
    Their C equivalent is:
    Code:
    int x;
    x = whatever;
    int *x;
    *x = whatever;
    For your problem, at least you know that the first swap is wrong and the second right. You need true temporary storage to swap two int's. The compiler might optimize the temp to an available register. You can declare temp volatile and it will not be put in a register. Maybe it will work for you.
    Code:
    ...
        goto johny_walker_red_label;
    johny_walker_blue_label: exit(-149$);
    johny_walker_red_label : exit( -22$);
    A typical example of ...cheap programming practices.

  9. #9
    Stressed Student :(
    Join Date
    Feb 2008
    Location
    Berkeley, CA
    Posts
    73
    Thanks I think I'll work on this a little bit more, so if i declare temp volatile, it doesn't save it in the register -- i'll try it out.

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Actually, it appears that move is a valid instruction.

    I don't think volatile is really necessary to solve what you are supposed to do. You need a temporary to store the value of one side you are swapping, but it doesn't matter if this is memory or a register.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Stressed Student :(
    Join Date
    Feb 2008
    Location
    Berkeley, CA
    Posts
    73
    I tried it with a volatile, a saved register, and a temp variable and they all worked. I think the question that was stated in my lab was really vague. I'll go ask a friend who t.a.'s for the class I think he'll be able to clear things out. Thanks for the help.

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Yes, that is probably best. But as I said before, just because the pointer is "not initialized" doesn't mean that the value is directly invalid - uninitialized variables have the value that happen to be in the memory location they end up at. This can be a valid memory location - in fact it quite often is. So "failure to fail" is not an indication of correctness.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A question of the MIPS assembly program
    By ok_good in forum Tech Board
    Replies: 0
    Last Post: 05-03-2006, 10:13 PM
  2. MIPS instructions
    By kokopo2 in forum C Programming
    Replies: 2
    Last Post: 08-24-2005, 01:02 AM
  3. Have you ever programmed for MIPS?
    By Maragato in forum A Brief History of Cprogramming.com
    Replies: 12
    Last Post: 10-05-2004, 08:32 PM