lwz
Load Word and Zero - 80 00 00 00
lwz
Instruction Syntax
Mnemonic | Format | Flags |
lwz | rD,d(rA) | - |
Instruction Encoding
1
0
0
0
0
0
D
D
D
D
D
A
A
A
A
A
d
d
d
d
d
d
d
d
d
d
d
d
d
d
d
d
Field | Bits | Description |
Primary Opcode | 0-5 | 100000 (0x20) |
rD | 6-10 | Destination register |
rA | 11-15 | Source register A |
d | 16-31 | 16-bit signed displacement |
Operation
if rA = 0 then EA ← EXTS(d) else EA ← (rA) + EXTS(d) rD ← MEM(EA, 4)
LWZ loads a 32-bit word from memory into a register. It calculates the memory address by adding a signed offset to a base register.
- Calculates address = base register + offset (or just offset if base register is r0)
- Loads the 32-bit word from that memory address
- Stores the word in the destination register
Note: This is the most commonly used load instruction in PowerPC. The memory address must be aligned to 4 bytes. If you use r0 as the base register, it's treated as 0 (not the contents of r0).
Affected Registers
None - This instruction does not affect any condition register fields or XER register bits.
For more information on memory addressing see Section 2.1.6, "Effective Address Calculation," in the PowerPC Microprocessor Family: The Programming Environments manual.
Examples
Basic Word Loading
lwz r3, 0(r1) # Load word from address in r1 lwz r4, 100(r2) # Load word from address r2+100 lwz r5, -50(r3) # Load word from address r3-50
Loading from Absolute Address
lwz r3, 0x1000(r0) # Load word from absolute address 0x1000 # Note: r0 treated as value 0, not register contents
Structure Member Access
# Load structure members (C-style struct) # struct Point { int x; int y; int z; }; lis r3, point_data@ha addi r3, r3, point_data@l lwz r4, 0(r3) # Load x member (offset 0) lwz r5, 4(r3) # Load y member (offset 4) lwz r6, 8(r3) # Load z member (offset 8)
Array Element Access
# Access elements in word array lis r3, int_array@ha addi r3, r3, int_array@l li r4, 5 # Array index slwi r5, r4, 2 # Multiply index by 4 (sizeof(int)) lwzx r6, r3, r5 # Load array[5] using indexed addressing # Or using displacement: lwz r7, 20(r3) # Load array[5] directly (5*4=20)
Function Pointer Loading and Calling
# Load and call function through pointer lis r3, function_table@ha addi r3, r3, function_table@l li r4, 2 # Function index slwi r4, r4, 2 # Multiply by sizeof(pointer) lwzx r5, r3, r4 # Load function pointer mtctr r5 # Move to count register bctrl # Call function
Global Variable Access
# Access global variables through GOT/TOC lis r3, global_var@ha lwz r4, global_var@l(r3) # Load global variable value # Alternative for position-independent code lis r3, _GLOBAL_OFFSET_TABLE_@ha addi r3, r3, _GLOBAL_OFFSET_TABLE_@l lwz r4, global_var@got(r3) # Load address from GOT lwz r5, 0(r4) # Load actual value
Stack Frame Access
# Access stack frame variables # Function prologue stwu r1, -64(r1) # Create stack frame stw r31, 60(r1) # Save r31 # Access local variables (negative offsets from frame pointer) lwz r3, 8(r1) # Load local variable at offset 8 lwz r4, 12(r1) # Load local variable at offset 12 # Access parameters (positive offsets from original stack pointer) lwz r5, 68(r1) # Load parameter (64 + 4) lwz r6, 72(r1) # Load next parameter
Object-Oriented Method Call
# Load virtual function table and call method lis r3, object_ptr@ha lwz r4, object_ptr@l(r3) # Load object pointer lwz r5, 0(r4) # Load vtable pointer (first member) li r6, 2 # Method index slwi r6, r6, 2 # Convert to byte offset lwzx r7, r5, r6 # Load method pointer from vtable mtctr r7 # Set up call mr r3, r4 # Pass object as 'this' pointer bctrl # Call virtual method
Configuration Register Access
# Load device configuration registers lis r3, device_base@ha addi r3, r3, device_base@l lwz r4, DEVICE_ID(r3) # Load device ID register lwz r5, STATUS_REG(r3) # Load status register lwz r6, CONFIG_REG(r3) # Load configuration register # Check device status andi. r7, r5, 0x0001 # Check ready bit beq device_not_ready # Branch if not ready andi. r7, r5, 0x8000 # Check error bit bne device_error # Branch if error
Linked List Traversal
# Traverse singly-linked list # struct Node { int data; struct Node* next; }; lis r3, list_head@ha lwz r4, list_head@l(r3) # Load head pointer traverse_list: cmpwi r4, 0 # Check for null pointer beq list_end # Branch if end of list lwz r5, 0(r4) # Load data member # Process data in r5 bl process_data lwz r4, 4(r4) # Load next pointer b traverse_list # Continue traversal list_end:
Hash Table Lookup
# Hash table lookup with chaining lis r3, hash_table@ha addi r3, r3, hash_table@l li r4, 0x12345678 # Key to search for li r5, 256 # Hash table size rlwinm r6, r4, 0, 24, 31 # Simple hash: key % 256 slwi r6, r6, 2 # Convert to word offset lwzx r7, r3, r6 # Load bucket head pointer search_bucket: cmpwi r7, 0 # Check for null pointer beq key_not_found # Branch if end of chain lwz r8, 0(r7) # Load key from entry cmpw r8, r4 # Compare with search key beq key_found # Branch if match lwz r7, 8(r7) # Load next pointer (skip value at offset 4) b search_bucket # Continue chain traversal key_found: lwz r9, 4(r7) # Load value from entry # r9 contains the found value b lookup_done key_not_found: li r9, 0 # Return null/not found lookup_done:
Graphics Vertex Loading
# Load 3D vertex data for graphics processing # struct Vertex { float x, y, z; int color; }; lis r3, vertex_array@ha addi r3, r3, vertex_array@l li r4, 5 # Vertex index li r5, 16 # sizeof(Vertex) = 4 floats mullw r6, r4, r5 # Calculate byte offset add r7, r3, r6 # Vertex address lwz r8, 0(r7) # Load x coordinate (as int bits) lwz r9, 4(r7) # Load y coordinate (as int bits) lwz r10, 8(r7) # Load z coordinate (as int bits) lwz r11, 12(r7) # Load color value # Move to floating-point registers for processing stw r8, temp_x(r1) # Store to stack stw r9, temp_y(r1) stw r10, temp_z(r1) lfs f1, temp_x(r1) # Load into FP registers lfs f2, temp_y(r1) lfs f3, temp_z(r1)
File Header Parsing
# Parse binary file header lis r3, file_buffer@ha addi r3, r3, file_buffer@l lwz r4, 0(r3) # Load magic number/signature lwz r5, 4(r3) # Load version number lwz r6, 8(r3) # Load file size lwz r7, 12(r3) # Load header size lwz r8, 16(r3) # Load number of sections # Validate header lis r9, MAGIC_SIGNATURE@ha ori r9, r9, MAGIC_SIGNATURE@l cmpw r4, r9 # Check magic number bne invalid_file # Branch if invalid cmpwi r5, SUPPORTED_VERSION # Check version bne unsupported_version # Branch if unsupported # Header validated, process sections mr r10, r3 # Current position add r10, r10, r7 # Skip to first section mr r11, r8 # Section counter process_sections: cmpwi r11, 0 # Check if more sections beq file_done # Branch if done lwz r12, 0(r10) # Load section type lwz r13, 4(r10) # Load section size # Process section based on type bl process_section # Pass r12=type, r13=size, r10=data add r10, r10, r13 # Move to next section subi r11, r11, 1 # Decrement section counter b process_sections file_done:
Memory Pool Management
# Memory pool allocation tracking # struct Block { size_t size; int free; struct Block* next; }; lis r3, memory_pool@ha addi r3, r3, memory_pool@l lwz r4, 0(r3) # Load first block pointer li r5, 1024 # Requested size find_free_block: cmpwi r4, 0 # Check for null pointer beq no_free_blocks # Branch if no more blocks lwz r6, 0(r4) # Load block size lwz r7, 4(r4) # Load free flag cmpwi r7, 1 # Check if block is free bne next_block # Skip if not free cmpw r6, r5 # Compare size with requested bge block_found # Branch if suitable size next_block: lwz r4, 8(r4) # Load next block pointer b find_free_block # Continue search block_found: li r7, 0 # Mark block as allocated stw r7, 4(r4) # Update free flag addi r3, r4, 12 # Return pointer to data area b allocation_done no_free_blocks: li r3, 0 # Return null pointer allocation_done: