If else in MIPS

2019-08-19 03:22发布

问题:

I am learning MIPS programming, in which I am trying to implement If else conditions. But the problem is when I enter 2 to select subtract condition, the program doesn't work. I know could have used BNE but I want to learn BEQ. Please tell me what is the problem is this code

.text

main:

li $t0,1
li $t1,2
li $t2,3
li $t3,4

li $v0,5
syscall

move $s0,$v0

beq $s0,$t0,ADDTN
ADDTN:


li $a0,40
li $v0,1
syscall

li $v0,5
syscall


move $s1,$v0

li $v0,5
syscall

move $s2,$v0

add $a0,$s1,$s2

li $v0,1
syscall

li $v0,10
syscall



beq $s0,$t1,SUBTN
SUBTN:

li $a0,50
li $v0,1
syscall

li $v0,5
syscall


move $s3,$v0

li $v0,5
syscall

move $s4,$v0

sub $a0,$s3,$s4

li $v0,1
syscall

li $v0,10
syscall

回答1:

for example:

beq $s0,$t0,ADDTN
ADDTN:
     # code for addition
     # ...
     # some syscalls
beq $s0.$t1,SUBTN
SUBTN:
 .
 .
 .

I have no idea what the syscalls do (I usually don't code for MIPS).

But you check for a condition, i. e. equality of $s0 and one of $tn, and on equality you jump to the routine that suits the case. Very well, but the routine is immediately following the BEQ instruction, so the branch is absolutely superfluous here. And further, if the condition is not met, the program continues with the code directly following the BEQ instruction.

The result is that the routines (add least ADDTN) are unconditionally executed. As said, I do not know what the syscalls do, but if addition works, I guess they are kinda jumps or so.

Anyway, you must rearrange your code so that depending on the state of the tested condition another branch of your code is executed. This is a generic "template":

        beq $s0, $t0, equal
        # this code is executed if $s0 and $t0 differ
         .
         .
        jmp notequal        # avoid also executing the code for equal
equal:
        # code for the case $s0 and $t0 hold the same value
         .
         .
notequal:
        # all that follows executes with no regard of the checked condition

There are other techniques for branching several cases like yours (you seem to have to check four operations, I guess), but you should start understanding the basics first.

[update: Well, actually it's not that different, just that the code blocks are spread wider... /update]

Have fun...



回答2:

As this is homework:

If it's equal, it will jump to the offset specified by the label. And if it's not equal, what code do you expect it to execute?



回答3:

If you are going to use branch on equals then your program should actually perform some branch that makes sense. Examine your branch instruction:

    beq $s0,$t0,ADDTN
ADDTN:

In MIPS you must remember that the PC (program counter) will simply advance line by line unless directed otherwise. A branch instruction can direct the PC to some other location in the program; however, in your code the branch instructions tell the PC to just advance to the next line which is exactly what the program would do without a branch instruction.

Also, if you only want these certain labels, ADDTN, SUBTN, to be executed, then each label must have a jump instruction at the end of its operation. For example, when ADDTN is finished the program should jump past SUBTN, unless of course you want SUBTN to also execute. Here is an example of what you could do. Have a series of branch instructions which divert the PC to specific operator labels and at the end of each label jump to an EXIT label.

    beq $s0, $t1, SUBTN    # if(input==2) {goto SUBTN}
    beq $s0, $t0, ADDTN    # if(input==1) {goto ADDTN}
    beq $s0, $t2, MULT     # if(input==3) {goto MULT}
    beq $s0, $t3, DIV      # if(input==4) {goto DIV}


ADDTN:
    # Code for addition
    j EXIT

SUBTN:
    # Code for subtraction
    j EXIT

MULT:
    # Code for multiplication
    j EXIT

DIV:
    # Code for division
    j EXIT

EXIT:
    # Code to exit
    j EXIT

Note: You should be able to visualize what will happen in this example if the value of $s0 is anything but 1, 2, 3, or 4. If none of the branch on equals causes the PC to jump to a label, then the program will execute the code in the ADDTN label. Also, if each label does not produce a jump to some ending label (EXIT) the program would continue executing the remaining labels.

If you want to perform an explicit else statement, consider the following example:

MAIN:    
    beq $s0, $t0, ADDTN    # if(input==2) {goto ADDTN}
    j SUBTN                # else {goto SUBTN}

ADDTN:
    # Code for addition
    j EXIT

SUBTN:
    # Code for subtraction
    j EXIT

EXIT:
    # Exit the program

In this example the first branch will check if the input correlates with the addition label. If it does, the PC will jump to that label; else if will advance to the next line which instructs a jump to the subtraction label.



标签: assembly mips