As you might guess, those are the instructions for adding and subtracting. Both are R-type instructions. These instructions assume that the registers containg bitstrings in 2C. However, there's nothing enforcing that the register contain representations in 2C. The instructions operate on them as if they were.
This is an interesting difference between languages like Java and ISAs. In Java, each variable has a type, and since the language is supposed to be type-safe, you may only call methods that are appropriate to the type.
In most ISAs, registers are treated as bitstrings. How those bits are interpreted depend on the instructions. There are no checks or flags to indicate a register holds a signed int or an unsigned int.
The specific instructions assume that the bitstrings in the register are of the appropriate representation, and operate as if they were, whether they do or they don't. This leaves the burden of accuracy on the programmer.
add $rd, $rs, $rt # R[d] <- R[s] + R[t] sub $rd, $rs, $rt # R[d] <- R[s] - R[t]The # indicates a comment, just like // is a comment in C++. The comments indicate the semantics. Addition, in this case, is signed addition in 2C. Subtraction is signed subtraction in 2C (which internally negates a copy of the $rt register in 2C).
Here is a specific example of both:
add $r1, $r2, $r3 # R <- R + R
sub $r1, $r2, $r3 # R <- R - R
Recall that R-type instructions have the destination
register first, followed by the two source registers (like an
|opcode||register s||register t||register d||shift amount||function|
|add $rd, $rs, $rt||000 000 (SPECIAL)||-||-||-||00000||100 000|
|sub $rd, $rs, $rt||000 000 (SPECIAL)||-||-||-||00000||100 010|
The dashes are 5-bit encoding of the register number in UB. For example, $r7 is encoded as 00111.