pete > courses > CS 202 Spring 24 > Lecture 15: mov, immediate values, and value extension


Lecture 15: mov, immediate values, and value extension

Goals


pop quiz!

what is -3 in 4-bit two’s complement?

1101

what about the same value in 8-bit two’s complement?

1111 1101

16-bit?

1111 1111 1111 1101

what’s the pattern?

if we want to increase the number of bits but retain the same value, fill with ones to the left

we’ll return to this in a bit


before we get back into specific ARM32 instructions, I have a confession

in the name of simplifying things for the scope of the course, I claimed that a certain collection of bits (23-27) in the instruction was the opcode—the bits that identify what operation the instruction performs

it’s a bit more complicated than that, and since we’re going to see some of that complication today, I figured why not inflict it all on you

here is the reference for ARM32’s add instruction, which we looked at last time:

 3   2                   1                   0
 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+---------------------------------------------------------------+
|       |0 0|0|0 1 0 0|S|  Rn   |  Rd   |               |  Rm   |
+---------------------------------------------------------------+

assembly:   add Rd, Rn, Rm

effect:     Rd <- Rn + Rm

example:    e0823003    add r3, r2, r3

I have filled in more bits and added more separators

ARM32 divides its various instructions into categories, one of which is "data processing", of which the add instruction is a member

the instruction category is identified by bits 26-27: 0 0 means "data processing"

I will defer the meaning of bit 25 for a few minutes

bits 21-24 identify the particular data processing operation; in this case, add


now, here’s a reference for ARM32’s subtract instruction, sub:

 3   2                   1                   0
 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+---------------------------------------------------------------+
|       |0 0|0|0 0 1 0|S|  Rn   |  Rd   |               |  Rm   |
+---------------------------------------------------------------+

assembly:   sub Rd, Rn, Rm

effect:     Rd <- Rn - Rm

example:    e0423003    sub r3, r2, r3

first, the differences:

there are a couple similarities worth noting:


this latter point is, in fact, going to hold for all arithmetic and logical operations that involve two operands

so a multiplication instruction, or a division instruction, or an instruction that performs XOR will use the same bits of the instruction to specify sources and destination

what about an instruction that only has one operand?

 3   2                   1                   0
 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+---------------------------------------------------------------+
|       |0 0|0|1 1 0 1|S|       |  Rd   |               |  Rm   |
+---------------------------------------------------------------+

assembly:   mov Rd, Rm

effect:     Rd <- Rm

example:    e1a00003    mov r0, r3

the "move" instruction takes a value from one register and puts it into another register

it’s a bit misleadingly-named, though, because the value in the source register isn’t modified

it might be more appropriate to think of the operation as "copy" instead of "move", but the name "move" has been used for this for decades, so it’s what we’re stuck with


we still haven’t addressed the problem we noted at the end of last lecture, however

namely, that it’s nice to be able to add the contents of registers (and now subtract or move them) but how do we actually get an interesting value into a register to begin with?

adding, subtracting, or moving the contents of registers that contain all zeroes doesn’t give us anything except more zeroes


therefore, I present to you the "move immediate" instruction:

 3   2                   1                   0
 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+---------------------------------------------------------------+
|       |0 0|1|1 1 0 1|S|       |  Rd   |         imm12         |
+---------------------------------------------------------------+

assembly:   mov Rd, #imm12

effect:     Rd <- extend(imm12)

example:    e3a0300a    mov r3, #10

this is an interesting one: there is no source register!

and yet we would assume (correctly!) that it has a similar effect to the mov instruction we just looked at: it puts a value in a register

this instruction uses an immediate value, however: an operand that comes, not from a register (nor from memory, which will we see soon), but from the bits of the instruction itself

so the result of this instruction is that the low 12 bits of the instruction (bits 0-11) are copied into Rd


there’s one problem, though: this is ARM32, so the registers each store 32 bits, but the immediate value here is only 12 bits

what do we do with the other 20 bits?

here’s one line of reasoning:

we might want to store either positive or negative numbers in registers

two’s complement is the natural choice (and indeed how ARM32 represents signed integers)

let’s assume we want to put our 12-bit immediate value into the 32-bit register and have it retain the same meaning

if the immediate value is 0000 0000 0011 (the 12-bit representation of 3), then, after the instruction executes, we would like the register to contain 0000 0000 0000 0000 0000 0000 0000 0011 (the 32-bit representation of 3)

if the immediate value is 1111 1111 1101 (the 12-bit representation of -3), then, after the instruction executes, we would like the register to contain 1111 1111 1111 1111 1111 1111 1111 1101 (the 32-bit representation of -3, following the pattern from the beginning of today’s discussion)

in both cases, we put the 12-bit immediate value in the low 12 bits of the register

in the case of a non-negative number, we fill the high 20 bits with zeroes

in the case of a negative number, we will the high 20 bits with ones

recall, though, that the most-significant bit of a non-negative number will always be zero and the most-significant bit of a negative number will always be one

this matches the bit we’re using to fill the high 20 bits!

we can refer to the most-significant bit of a two’s complement number as the sign bit

so, no matter whether the value is positive or negative, we take the 12-bit value and extend (copy) the sign bit to fill all the more significant bits of the larger space

this is a process called sign extension


an alternative to sign extension is zero extension, where we fill the more significant bits with zeroes

we will see uses of both

and you might be tempted to assume that we will see one of them used for the 12-bit immediate value in the move immediate instruction

but you would be wrong!

the move immediate instruction uses a different (more complicated) method

I presented zero-extension and sign-extension first, with no intention of actually making use of either today, because a) they’re simpler and b) you need to know them


so what does move immediate do?

the 12-bit immediate value is actually broken down into two parts: a rotation and a value:

 1   0
 1 0 9 8 7 6 5 4 3 2 1 0
+-----------------------+
|  rot  |     value     |
+-----------------------+

the value is the actual bits that get stored in the register

the rotation is an operation we perform on the bits before they arrive in the register

here’s the process:

(this operation, wherein we shift and any bits that fall off are tacked onto the other end, is called rotation)


example the first (in which "abcdefgh" represent arbitrary bits, a trick I stole directly from the official ARM32 documentation):

0001 abcdefgh

we first zero-extend the 8-bit value to 32 bits:

0000 0000 0000 0000 0000 0000 abcd efgh

then we interpret the rotation as an unsigned integer: 1

we multiply it by 2: 2

then we rotate by that many spots:

gh00 0000 0000 0000 0000 0000 00ab cdef

example the second, this time with less commentary:

imm12:

0101 abcdefgh

zero-extend:

0000 0000 0000 0000 0000 0000 abcd efgh

rotate by 5 * 2 = 10:

00ab cdef gh00 0000 0000 0000 0000 0000

there are variants of the add and sub instructions that also take an immediate value as the second operand:

 3   2                   1                   0
 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+---------------------------------------------------------------+
|       |0 0|1|0 1 0 0|S|  Rn   |  Rd   |         imm12         |
+---------------------------------------------------------------+

assembly:   add Rd, Rn, #imm12

effect:     Rd <- Rn + extend(imm12)

example:    e283300a    add r3, r3, #10
 3   2                   1                   0
 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+---------------------------------------------------------------+
|       |0 0|1|0 0 1 0|S|  Rn   |  Rd   |         imm12         |
+---------------------------------------------------------------+

assembly:   sub Rd, Rn, #imm12

effect:     Rd <- Rn - extend(imm12)

example:    e243300a    sub r3, r3, #10

we call these "add immediate" and "sub immediate", respectively

note that the opcodes are the same as in the "add register" and "sub register" instructions we looked at earlier

the difference is in bit 25: this is the bit that specifies whether we are using an immediate value or not


the sub immediate instruction allows us to subtract an immediate value from the contents of a register

but what about the opposite: subtract the contents of a register from an immediate value?

we need a different instruction: reverse subtract (rsb)

 3   2                   1                   0
 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+---------------------------------------------------------------+
|       |0 0|1|0 0 1 1|S|  Rn   |  Rd   |         imm12         |
+---------------------------------------------------------------+

assembly:   rsb Rd, Rn, #imm12

effect:     Rd <- extend(imm12) - Rn

example:    e263300a    rsb r3, r3, #10

Definitions

The following definitions introduced in this lecture are fair-game for future quizzes. You will be expected to give the exact definition as provided in these lecture notes.

Mechanical Skills

The following mechanical skills introduced in this lecture are fair-game for future quizzes. You may access practice questions (which will exactly resemble the questions on the quizzes) on weathertop.

t1p2m02    assemble/disassemble data-processing instructions (immediate)

Last modified: