When we load a register or memory location with a value (e.g.
MVI 3A or
MVI 53), what initializes register or memory location with that specific value? It is the CPU who performs the initialization, right? But where are those values drawn from?
Note: since you did not mention which instruction set architecture you are asking about, I have to make some assumptions and guesswork in my answer. Also, it looks like the textbook or the learning material refers to an architecture that is not the same as today's "desktop CPUs", so please cite the name of the textbook or learning material so that we know what architecture it is referring to.
Without further information, my internet search seems to indicate it may be referring to this book: Microprocessors and Microcontrollers: Architecture, Programming and System Design 8085, 8086, 8051, 8096
MVI refers to immediate. In assembly programming, an "immediate value" is a value that is directly encoded into the instruction itself.
For simplicity I will first focus on the case of architectures having a fixed instruction size, say, each assembly instruction is 32-bit.
Part of the 32-bit is used to store the opcode that specifies the operation, such as addition, subtraction, load from memory, store to memory, branching, etc.
MVI is the mnemonic for an opcode that will set a particular register to a particular value.
The remaining bits of the 32-bit instruction are used for purposes depending on what the opcode is. Different opcodes use those remaining bits in different ways.
MVI, some of the remaining bits specify which of the CPU register will be updated with that "immediate value". The rest of the bits are used to encode this immediate value.
I should emphasize that, typically, the CPU does not need to make an additional memory request to fetch this immediate value. The reason is that the CPU has already loaded the entire instruction (32-bit) from memory, before it can perform instruction decode step on it. Thus, the opcode, the register identifier, and the immediate value are all loaded into the instruction decoder.
The instruction decoder can pass this immediate value into the arithmetic and logic unit (ALU) via one of the ALU input ports. The ALU will be set to perform nothing - pass the same input value as output. The register file is configured to accept this value from the ALU output port, and store it into the destination register, according to the instruction decoder's parsing of the
The immediate value is technically part of the instruction.
Similar instructions exist across a lot of architectures, though details might differ.
In some cases, the architecture word size is 32-bit, meaning that the ALU and memory operations are 32-bit wide, and the instruction size is also fixed at 32-bit. Since the opcode and the register identifier took up some of the instruction bits, it is not possible for the immediate value to be 32-bit. Instead, the immediate value is limited to fewer number of bits. For example, if opcode is 6-bit and the register identifier is 5-bit (supporting up to 32 registers), the remaining number of bits available for the immediate value is
32 - 6 - 5 == 21 bits. Depending on the architecture, this 21-bit immediate value might be interpreted as signed or unsigned.
In some other architectures, the immediate value is not packed into the instruction itself, but is stored immediately next to it.
|| Address | Instruction data || || 0 | MVI || || 2 | 0x1234 || || 4 | whatever instruction that follows ||
For these architectures, it might require an additional memory access. The
MVI instruction at address
0 causes the instruction decoder to treat the data at address
2 not as instruction, but as the value for the
Although this design allows the
MVI instruction to load the full-width data (16-bit) into the register, notice that it creates a danger for a branch instruction to specify address
2 as the jump target. Since the data can be any arbitrary 16-bit value, a branch instruction that lands at this address will mis-interpret that data as an instruction opcode (to whatever opcode that happens to have the same bit patterns as that 16-bit value), and therefore will execute an arbitrary instruction that is unintended by the assembly language programmer.
In yet some other architectures, it is possible that they do not have the equivalent of
MVI at all. Instead, the value must be loaded from memory, typically named a
|| Address | Data / Instruction || || 0 | LD R1, (address) 128 || || 2 | whatever instruction that follows || || ... | ... || || 128 | 0x1234 ||
MVI (Move Immediate) copies an immediate value from the memory location that is adjacent to the MVI opcode itself (the "operand"). The value is baked into the machine code when you assemble it, and will exist in the code segment (the memory block that contains the executing instructions).
Generally in assembly languages there are both instructions and operands.
When loading a value, an instruction will have an operand specifying the data the operation needs. This could be the value of another memory location or a literal value, similar to how one can have an integer or pointer to integer in C. Perhaps there are different machine code instructions for the two varieties, or perhaps there is an indicator built-in to the operand to specify how to interpret it. At the assembly level, this is irrelevant.
When the CPU loads the instruction and executes it, it will either store the literal value where it belongs or load the value from memory and store it.
This means the values are drawn from the instruction's operand, but the value could be another level of indirection deep and stored at another memory location.