Reputation: 325
Is there a single LC3 instruction to load a value into a register? I need to write some assembly code and I come to where I need to write just a single instruction to store the value 1 in R1.
Upvotes: 2
Views: 12025
Reputation: 364190
LC-3 doesn't have a move-immediate. The instruction set includes AND/ADD/NOT (with register or immediate), LEA, and load instructions.
add
-immediate with a zeroed registerIf you have a zeroed register, you can materialize any small constant into a register with add
(5-bit sign-extended immediate, value-range [-16, +15]
).
(Zero is special: It can be created by AND regardless of previous register contents.)
and r7, r7, #0 ; R7 = 0. Somewhere in your program or function
add r0, r7, #-16 ; R0 = 0 + -16 = -16
add r1, r7, #15 ; R1 = 15
The source register doesn't have to be zero; any other known constant within -16..+15 of your desired value can work. e.g. if you know R4
is 3
, you can get R1=1 with add r1, r4, #-3 + 1
. But that's complicated to keep track of, probably only worth doing if you're optimizing for size or speed.
ld
uses a PC-relative addressing mode so it can load nearby words (-256 .. +255).
ld r1, ONE
ONE .fill 1 ; elsewhere in your program
If you need a couple simple constants at various different places in your program, and don't want to leave one of your precious few registers zeroed all the time, this is a single-instruction way to get a constant that doesn't require any setup.
If you want to just return 0 or non-0 from a function, you may not care which non-zero value you create. and
can only clear bits, not set them.
add
and not
aren't safe either if you don't know the value of any register; there's always an input that will result in 0
for them. e.g. add r0, r1, #1
wraps to 0 if the original value was 0xFFFF aka -1
.
But LEA can create a value that depends only on the program counter (which is known) and the 9-bit signed immediate in the instruction ([-256 .. +255] range). We know that address 0
isn't going to be in the middle of our program, so any address is fine if we just want non-0. Often we begin LC-3 programs at .orig x3000
, so small numbers like 1
can't be generated by LEA, but if we just need non-0 that's fine.
.orig x3000
...
lea r0, nonzero
...
nonzero ; put this label literally anywhere in your program
var1 .fill 1
The nonzero
label is attached to the same address as var1
, which is totally fine. You could even put it on the LEA instruction itself, like
nonzero lea r0, nonzero
If you can use a .orig
that puts your program close to the start of memory address-space, small constants like 1
can be created with LEA. Like perhaps
.orig 0
address0
...
lea r1, address0+1 ; R1 = 1, if this is the right syntax for this
...
Upvotes: 0
Reputation: 11
Yes there is. it is: LD R0,Param1
What this means is that it will load the value of Param1 into Register 0.
Upvotes: 0
Reputation: 433
LD R1, value
Do a .fill on "value" with whatever value you want to load into R1. I don't believe there's a way to load a literal value into a register with a single line, but you can do it with one instruction and one label.
Upvotes: 2