liveBook · Manning

Machine instruction

As explained in Rust in Action: Systems programming concepts and techniques

An instruction is an encoded command that a processor can fetch and execute, including commands expressed in assembly language.

A machine instruction is an encoded command that a processor interprets and executes. Instructions and the data they operate on can share the same numeric encoding, allowing software to emulate another computer’s instruction set. section 5.7

A minimal CPU processes an instruction through a short sequence:

  • Initialize the CPU and its registers. section 5.7.1
  • Load operand values into registers and place an opcode in the current-operation field. section 5.7.1
  • Read and split the opcode into fields identifying the operation and its operands. section 5.7.1
  • Dispatch the decoded instruction and perform its operation, such as adding one register to another. section 5.7.1

Decoding a CHIP-8 addition instruction

The hexadecimal opcode 0x8014 encodes an addition involving registers 0 and 1: 8 identifies the two-register operation, 0 and 1 identify the registers, and 4 identifies addition. With register values 5 and 10, executing it adds the second value to the first. section 5.7.1

Listing 5.20 Reading the opcode
 impl CPU {
   fn read_opcode(&self) -> u16 {                      #1
     self.current_operation                            #1
   }                                                   #1
 
   fn run(&mut self) {
     // loop {                                         #2
       let opcode = self.read_opcode();
 
       let c = ((opcode & 0xF000) >> 12) as u8;        #3
       let x = ((opcode & 0x0F00) >>  8) as u8;        #3
       let y = ((opcode & 0x00F0) >>  4) as u8;        #3
       let d = ((opcode & 0x000F) >>  0) as u8;        #3
 
       match (c, x, y, d) {
           (0x8, _, _, 0x4) => self.add_xy(x, y),      #4
           _  =>  todo!("opcode {:04x}", opcode),      #5
       }
     // }                                              #6
   }
 
   fn add_xy(&mut self, x: u8, y: u8) {
     self.registers[x as usize] += self.registers[y as usize];
   }
 }

Inspect the decoding loop that extracts opcode fields, matches an instruction, and calls the corresponding CPU operation. section 5.7.1

How Rust in Action: Systems programming concepts and techniques covers it

How deep it goes
Builds from one addition instruction through opcode decoding and dispatch, stopping at a minimal CPU without memory.
Examples
Demonstrates CHIP-8 opcode 0x8014, register addition, opcode-field extraction, and a CPU decoding loop.
What you can do after
Builds a minimal CPU emulator that loads registers, decodes hexadecimal instructions, and executes an addition operation.
How it connects
Connects machine instructions with CPU emulation, opcodes, registers, operands, functions, pointers, stacks, and assembly language.

Also explained in

Compare how 2 books explain machine instruction →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Rust in Action: Systems programming concepts and techniques. The section links point to the parts of the book it draws on.