'Understanding address assignment to registers via assembly instructions
If I have a CPU/system with the following characteristics...
- 16 bit architecture (16 bit registers and bus)
- 8 total registers
- A set of 64 assembly instructions
And assuming my assembly instructions follow the format...
OPCode (6 bits) + Register (3 bits) + Register (3 bits) + Unused (4 bits)
** Example Instructions (below) **
Assembly: LOAD R1, R7 (Loads value of address stored in R1 into destination register R7)
Machine: 110000 001 111 0000
Assembly: STORE R1, R7 (Stores value in R1 into destination address stored in register R7)
Machine: 110001 001 111 0000
These types of instructions make sense to me because all of the required bits fit nicely into a 16 bit format and thus into the instruction register (which hold 16 bits), but I am confused on how one gets the desired address into a register to begin with due to this instruction length constraint?
If an address is 16 bits on this system, it seems to me like I would need more than 16 bits to represent an instruction that would assign an address value to any given register before I could even use something like a LOAD or STORE instruction...
OPCode (6bits) + destinationRegister (3 bits) + addressLiteral (16 bits) ???
However, something like this would not fit in my 16 bit instruction register. What am I not understanding here? Any help is greatly appreciated, thanks!
Solution 1:[1]
Fixed-length instruction sets:
LC-3, an 8 register machine, has fixed sized 16-bit instructions: it allows a 9-bit offset in certain 16-bit instructions. The 9-bit offset is used as an immediate to form a pc-relative address, from which a full 16-bit value is loaded as data. So, the trick there is to locate the full 16-bit value as data, somewhere nearby the code that is using it (e.g. within +/-256 words).
MIPS is a 32-bit instruction set, in a 32-bit address space. Using two instructions each having 16-bits of immediate value, a full 32-bit address can be composed.
Hack / nand2tetris has 16-bit instructions and has a special form for loading constants/address, the instruction form has one bit that says whether it is an A-type, which then allows 15 bits of constant or address.
MARIE, an accumulator machine, has 16-bit fixed length instructions, but only 4k of memory, so allows a 12-bit absolute address embedded in the 16-bit instructions.
PDP-8, an accumulator machine, has 12-bit instructions in a 12-bit address space. Instructions can directly reference nearby memory (within the same 128 word page as the code), or any thing on the zero page (lowmem, also 128 words).
Variable length instruction sets often allow a full length immediate following the instruction, such are x86, 68000, others. The processors will automatically include the size of such an immediate in the full length of the instruction.
To go more meta, instruction sets have formats, and the formats within an instruction set will vary to accommodate different kinds of operations, say, 3 reg, vs. 2 reg plus large-ish immediate. It all goes to instruction encoding, and part of the idea here is to offer software the features it needs, while also keeping the hardware implementation manageable.
When designing an ISA, there's a fair amount to think about. One thing is position independent code, which allows code to be loaded anywhere in the address space, and even shared at different locations in different address spaces; ideally code will run without any runtime relocations so the code can be fully immutable. There are also some considerations for dynamically loadable shared libraries (DLLs).
Thus, pc-relative addressing modes are very useful, and, absolute addresses should be confined to data and not allowed in code, unlike LC-3, MARIE, PDP-8.
Solution 2:[2]
I am assuming this is a fictional instruction set architecture since based of the question it doesn't seem real.
Addresses are commonly loaded from the program using "immediate" style instructions and therefore would require an instruction outside of the form of "op + reg1 + reg2 + padding"
For example, in MIPS you can use Load Upper Immediate and Load Immediate to load a 32 bit value into a register with two 32 bit instructions.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Stephen Klein |
