News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

IF-OR-THEN-ELSE construction

Started by Herakles, May 02, 2010, 02:09:19 PM

Previous topic - Next topic

Herakles

Hi everybody! :U

I am using PCSpim and I have to do an exercise which really drives me crazy:

"Translate the following program fragment into MIPS code ($t0 must contain the variable a).

IF (a < 0) OR (a > 99) THEN
   a := a - 10;
ELSE
   a := a - 1;
END;

Please note: the expression a > 99 will be only analysed in case a < 0 is false."

Since I am totally new to SPIM, I have no idea how to implement this exercise.
I think a XOR construction is necessary and they don't ask for a whole working program, but only for a specific fragment. So I would write:

main:   xor   (bltz a), (bgt a, 99)

then:


But the compiler gives me a syntax error right after xor.

Can you please help me?

I really appreciate that.

Regards,
Herakles.

Slugsnack

From what I remember of MIPS conditionals can be implemented by comparing a register to the zero register then doing conditional branching based on that. So subtract the two things you want to test for equality and compare the result. If you have problems later I'll write some code for you. Give it a go and post up here :)

You don't need a XOR. Just test the first condition. If true, branch to the IF code. If not, test the second condition. If that one is true, branch to the IF code again. Else, fall through to the ELSE code. Simple as that ^_^

Do you need a 'template' for a SPIM program at all ? A fully working program is not hard to produce at all.

In MIPs you do not put operands in brackets. Also you can not xor two instructions either.. Instructions are performed one at a time. Try to implement it as I described.

Herakles

Quote from: Slugsnack on May 02, 2010, 02:19:33 PM
From what I remember of MIPS conditionals can be implemented by comparing a register to the zero register then doing conditional branching based on that. So subtract the two things you want to test for equality and compare the result. If you have problems later I'll write some code for you. Give it a go and post up here :)

Thx Slugsnack.
I am a completely layman to Assembler...

Do you think it's wrong using xor?

Slugsnack

Yes sorry, edited my post just before you replied. Try and follow the method I described. Oh yeah.. forgot about BLTZ, that will work too. Just try and make something, post it up here and I'll tell you what's wrong with it.

Herakles

Quote from: Slugsnack on May 02, 2010, 02:38:43 PM
Yes sorry, edited my post just before you replied. Try and follow the method I described.

Thanks, Slugsnack for the amazing support. :U

   .text
main:   li   $t0, 15

if:   bltz   $t0, then
   bgt   $t0, 99, then
   b   else

then:   sub   $t0, $t0, 10

else:   sub   $t0, $t0, 1


I hope, this code is correct...

EDIT:
Do you think its OK that I have initialised $t0 with 15?
In case I initialise it with a, it certainly doesn't work...

Slugsnack

Your 'then' code falls through to your 'else' code so you want to put an unconditional branch after it to some exit at the end which the else code could fall through to.

Realistically, a variable is probably in memory so you wouldn't be loading an immediate, so maybe consider using 'lw' instead of 'li'. To solve the falling through problem, just define a label after the 'else' and have it so after your 'then' 'sub', it branches to that label. I don't remember precisely, but I'm not sure SUB can take an immediate value for its parameters. I think you'd have to load those constants into another register and do the sub like that. I'm not 100% sure since last time I programmed MIPS was a while ago. Your best bet is to check the documentation or try to assemble it in SPIM and see if you get any errors.

If I was doing this for an assignment, I would not initialise 'a' as 15. At least not as an immediate. I would declare it in the data section, initialising it to some value and then put a comment explaining.

Herakles

My problem is, that I am a beginner, so I don't have the feeling, how the compiler behaves...
Does it check, if lw  $t0, a is true and if yes, it jumps to then, or does it afterwards automatically check if bltz $t0, then is true, before it jumps to then?

I really have problems fixing this code with your suggestions, because this OR still irritates me (without this OR, this would be the easiest exercise)...

.data
a: .word 15

.text
main: lw $t0, a

bltz $t0, then
bgt $t0, 99, then
b else

then: sub $t0, $t0, 10

else: sub $t0, $t0, 1

Slugsnack

'lw $t0, a' can't be true or false. It is merely instructing the CPU to load the word at label 'a' into register $t0. It is completely independent of any other instruction. At runtime, this happens. Then afterwards, the instruction 'bltz $t0, then' is evaluated. That means at runtime, the compiler checks the value of $t0 and IF it is less than zero, it will branch to 'then'. If not, it just falls through to the next instruction.

For the sub, I wonder if you can use ADDI with a negative third operand. Try and assemble your code and see if it is at least syntactically correct. You have also yet to add the code to stop the 'then' code falling through to the 'else' code.

You should not worry too much about the OR. What I have advised you to do can be described as 'lazy evaluation'. You are evaluating each condition only when necessary. Another way, less efficiently would be to evaluate both, storing the results in different registers. Then you would OR those registers and branch conditionally on that. I hope you can understand why the current method is better.

Welllll if I get bored later, I'll SSH into school and use the SPIM there to test your proggy. Lazy to install it on my box..

// edit : Couldn't resist.. got bored. Found the source for the compiler I wrote last term and generated some code.
http://img413.imageshack.us/img413/1644/77138900.png

Hope you get the idea now. And btw, bad variable names is because they are auto-generated by my compiler code. You'll notice my compiler generated a 'sw' and 'li' instruction. That sort of really depends on your situation and how you wish to define a variable as..

Here's a different piece of code I compiled that you also may be interested in :]
http://img146.imageshack.us/img146/2/25116878.png

Can't find the final version of my source so there are some optimisations missing. For example.. in the second screenshot, there is not really a need to use $v1, we can just operate straight on $v0. Hope you get the idea..

Herakles

Thanks again Slugsnack, especially for the excellent explanation! :U

.data
a: .word 15

.text
main: lw $t0, a # $t0 := a

bltz $t0, then # IF a < 0
bgt $t0, 99, then # IF a > 99
b else

then: sub $t0, $t0, 10 # THEN $t0 := $t0 - 10
b endif

else: sub $t0, $t0, 1 # ELSE $t0 := $t0 - 1

endif: # END;(*IF*)



QuoteFor the sub, I wonder if you can use ADDI with a negative third operand. Try and assemble your code and see if it is at least syntactically correct.

What do you mean with ADDI?

I didn't get any error messages.

Slugsnack

Yeah sorry.. haven't messed with MIPS for a while.. so uhh duhhhh moment. Anyway check out the images I posted above.

Herakles

Amazing. I wish I had your program skills...

Thanks for the pics, but as I said: I am raw recruit. :red

BTW: I don't think they expect us to become good programmers. They want us more to be able to read code and to create small programms...

Would you say that this is acceptable as a solution to the exercise?

.data
a: .word 15

.text
main: lw $t0, a # $t0 := a

bltz $t0, then # IF a < 0
bgt $t0, 99, then # IF a > 99
b else

then: sub $t0, $t0, 10 # THEN $t0 := $t0 - 10
b endif

else: sub $t0, $t0, 1 # ELSE $t0 := $t0 - 1

endif: # END;(*IF*)

Slugsnack

Don't know, looks fine to me if they're not expecting a full solution :] As you can see, it's pretty much identical to the first code generated by my compiler.

Herakles

I don't think they want a full solution... At least they didn't ask for it in the task. I will see when I get the exercise back in few days. :green

Thank you very much for your help.

Cya

Slugsnack

Btw since you seemed to have some problems understanding the concepts of assembly a bit earlier let me use an analogy. We can take a 'context' of a program at any given time. This context consists of things that represent its current state. This could include next instruction to be executed, register values, stack values, etc. Each time an instruction is executed, we modify this state and this context changes. So you have an initial state and as we do each instruction, a part of the context is changed. When we get onto conditional branches, depending on the definition of the instruction, the computer looks at this context and does something based on it. Sometimes, like in your case, we can know what this context will actually be. Sometimes, we have true variables, like the second code I generated which gets user input. The flow of the program is then completely non-deterministic.

Damn.. I suck at explaining. I'll just stick to playing Street Fighter from now on..

Herakles

Your explanation (and of course all your other explanations) is very good and helpful! :U

Many people tend to become sarcastic in case a new member is searching for help in the forums. So I really do appreciate your no-nonsense work.

I'll give you the results when they have finished the correction, but I guess it will take a couple of days...


Regards,
Herakles.