Reputation: 1
slt $t2, $t0, $t1
beq $t2, $0, ELSE
j DONE
ELSE: addi $t2, $0, 3
DONE:
Im required to convert beq $t2, $0, ELSE to to machine language in hexadecimal and im not really sure how to do it? I know ur suppose to follow the format beq rs, rt, label but the thing is there is an ELSE there so what do i do from there? Also why is ELSE used before it is defined? Why is this permitted?
Upvotes: 0
Views: 331
Reputation: 26646
BEQ
is a pc-relative branch (that is done relative to the next instruction after it). It is an I-Type instruction with an immediate, whose value is added to the pc (pc-next) in order to form the branch target. When the immediate has the value 0, it is the same as saying branch to the very next instruction (don't skip ahead or back). When the immediate has the value (+)1, that says skip ahead 1 instruction, and -1 says go back and rerun this very instruction again. -2 says go back one instruction from the branch itself, etc.. (Obviously values of 0 and -1 are not helpful in real code, but it is good to know what they (would) mean.)
The j
instruction is different; though it also has an immediate, it is larger, and further, it is encoded using partial absolute addressing rather than pc-relative addressing. Because of that behavior, you will have to know the address of this target label DONE:
to create the immediate value to make it jump there. (Whereas with beq
, knowing the difference is all that is needed.) You haven't shown code addresses, but likely if you read your problem statement more closely, it will tell you the address of the first instruction, and from that you can derive the address of the DONE:
label as it is simply 4 instructions from the start.
Both branches and jumps keep the PC 4 byte aligned. Because of this, the lower 2 bits of the immediate would always be zero, and hence are not encoded in the instruction — this allows the immediates to have larger ranges than otherwise. These low 2 bits, which are both zero, are regenerated by the processor by shifting the immediates (left by 2) during usage. (For this reason the pc-relative branches work with instruction counts instead of byte addresses; similar is true for jumps).
Also why is ELSE used before it is defined? Why is this permitted?
As Michael says, code would be hard to write without that. This is called a forward reference, and resolving such references are one of the main jobs of the assembler.
Forward references are used in control structures like if-then-else (as in the case you present) and while loops (to exit them, for example);
An if-then-else statement typically has 2 forward references — one to skip ahead (around/over the then-part) to the else-part when the if-condition is false, and one for the then-part to skip ahead around/over the else-part (and on to the next statement after the if-then-else).
A while loop, typically has at least one forward reference used to exit the loop, by skipping around/over the entire loop so as to continue to execute the next statement after the loop.
Forward references are also used in function calls when the called function is physically located after the calling function in the assembly file.
References (forward and backward) are one of the main values in writing assembly instead of machine code, which is that the assembler computes the immediates instead of humans having to do so, especially as code is edited, for example, immediates need to be changed and this would be very tedious to do by hand.
Upvotes: 1