"Large" numbers and
"small" numbers
Why ARM
cannot
store a 32 bits number
into a register
with
one instruction
Why the
ARM process
cannot
store a
32 bits
(binary) number into a
register with
1 instruction:
- ARM instructions
are 4 bytes or 32 bits
long:
<------------------------------ 32 bits ----------------------->
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- To represent a
32 bits
(binary) number,
you need to use
32 bits:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|x|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- ARM
cannot
use
1 instruction:
to
move a
32 bits number to
a register
because:
- The ARM instruction
would have
no
space left
to encode/represent
the operation code !!!
|
|
ARM must
use
two instructions
(movw and movt) to
move a
32 bits
binary number into
a register
The movw
ARM assembler instruction
- Syntax of the
movw
instruction:
movw rN, #x // x = a value between 0 .. 216-1
|
Effect:
-
Store
the 16 bits
binary number x
in the
lower 16 bits
of the register rN
-
Clear the
upper 16 bits in
the register
rN
|
- Example:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
R0 = |1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
After executing movw R0,#15 (15 = 0000000000001111 in 16 bits)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
R0 = |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1|1|1|1|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
DEMO:
/home/cs255001/demo/asm/2-mov/movw.s
The movt
ARM assembler instruction
- Syntax of the
movt
instruction:
movt rN, #x // x = a value between 0 .. 216-1
|
Effect:
-
Store
the 16 bits
binary number x
in the
upper 16 bits
of the register rN
-
Leave the
lower 16 bits in
the register
rN
unchanged
|
- Example:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
R0: |1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
After executing movt R0,#15 (15 = 0000000000001111 in 16 bits)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
R0: |0|0|0|0|0|0|0|0|0|0|0|0|1|1|1|1|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
DEMO:
/home/cs255001/demo/asm/2-mov/movt.s
How do we
use movw and
movt to
store a
32 bits number into a register
- We break the
32 bits binary number into
2 (equal) halves:
<------------- 32 bits binary number ---------->
+-----------------------+-----------------------+
| most significant bits | least signficant bits |
+-----------------------+-----------------------+
<-- 16 bits bin num --> <-- 16 bits bin num -->
|
-
First:
use the
movw
instruction to
move
the least significant 16 bits
into the
register:
<------------- 32 bits binary number ---------->
+-----------------------+-----------------------+
| most significant bits | least signficant bits |
+-----------------------+-----------------------+
<-- 16 bits bin num --> <-- 16 bits bin num -->
-
Then: use the
movt
instruction
to
move the
most significant 16 bits
into the same register
<------------- 32 bits binary number ---------->
+-----------------------+-----------------------+
| most significant bits | least signficant bits |
+-----------------------+-----------------------+
<-- 16 bits bin num --> <-- 16 bits bin num -->
|
How do we
use movw and
movt to
store a
32 bits number into a register
- Example:
move
the value 65540(10)
(=
0000000000000001 0000000000000100)
into reg r0:
+---------------------------------+
R0 = | 00000000000000010000000000000100|
+---------------------------------+
<--- 16 bits ---><--- 16 bits --->
|
-
First:
use the
movw r0, #4
instruction to
move
0000000000000100
into
r0:
+---------------------------------+
R0 = | 00000000000000000000000000000100| // Note: the upper 16 bits are incorrect
+---------------------------------+
<--- 16 bits ---><--- 16 bits --->
-
Then: use the
movt r0, #1
instruction
to
move
0000000000000001
into the
same register
+---------------------------------+
R0 = | 00000000000000010000000000000100| // R0 = 65549 !!!
+---------------------------------+
<--- 16 bits ---><--- 16 bits --->
|
Assembler support
for the movw and
movt
instructions
The ARM assembler provides
2 operators
to help you use
the movw and
movt
instructions:
How do we move (= put) a
large (binary) number into a register
Suppose we have arbitrary 32 bits number X:
X = UUUUUUUUUUUUUUUULLLLLLLLLLLLLLLL
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
upper 16 bits lower 16 bits
We store X into register r0 using the 2 assembler instructions:
+----------------------------------+
r0 = | 32 bits |
+----------------------------------+
|
movw r0, #:lower16:X |
V
+----------------------------------+
r0 = | 0000000000000000LLLLLLLLLLLLLLLL |
+----------------------------------+
|
movt r0, #:upper16:X |
V
+----------------------------------+
r0 = | UUUUUUUUUUUUUUUULLLLLLLLLLLLLLLL | = X !!
+----------------------------------+
|
Example:
storing a large number into a register
- Problem:
- Store the
number
1234567 (decimal) into
register R0
|
-
Incorrect way:
mov r0, #1234567 // Illegal value for mov
|
-
Correct solution:
movw r0, #:lower16:1234567 // 1234567 % 216 = 54919
movt r0, #:upper16:1234567 // 1234567 / 216 = 18
|
|
DEMO:
/home/cs255001/demo/asm/2-mov/mov-large.s
❮
❯