lhz
Load Halfword and Zero - A0 00 00 00
lhz

Instruction Syntax

Mnemonic Format Flags
lhz rD,d(rA) -

Instruction Encoding

1
0
1
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 101000 (0x28)
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 ← 0x0000 || MEM(EA, 2)

A halfword (16 bits) is loaded from memory and placed in the low-order 16 bits of register rD. The upper 16 bits of rD are set to zero. The effective address is computed by adding the sign-extended displacement to the contents of register rA, or zero if rA is 0.

Note: The effective address should be halfword-aligned (divisible by 2) for optimal performance. If rA=0, it is treated as the value 0, not the contents of register 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 Halfword Loading

lhz r3, 0(r1)           # Load halfword from address in r1
lhz r4, 100(r2)         # Load halfword from address r2+100
lhz r5, -50(r3)         # Load halfword from address r3-50

Unicode Character Loading

# Load Unicode characters (16-bit)
lis r3, unicode_string@ha
addi r3, r3, unicode_string@l
li r4, 5                # Character index
slwi r5, r4, 1          # Multiply by 2 (sizeof(wchar_t))
lhzx r6, r3, r5         # Load unicode_string[5]
# Or using displacement:
lhz r7, 10(r3)          # Load character at offset 10 (index 5)

Network Protocol Header Parsing

# Parse network packet header with 16-bit fields
lis r3, packet_buffer@ha
addi r3, r3, packet_buffer@l

lhz r4, 0(r3)           # Load packet type (16-bit)
lhz r5, 2(r3)           # Load packet length (16-bit)
lhz r6, 4(r3)           # Load source port (16-bit)
lhz r7, 6(r3)           # Load destination port (16-bit)
lhz r8, 8(r3)           # Load checksum (16-bit)

# Validate packet length
cmpwi r5, 1500          # Check against maximum MTU
bgt invalid_packet      # Branch if too large

Audio Sample Loading (16-bit)

# Load 16-bit audio samples
lis r3, audio_buffer@ha
addi r3, r3, audio_buffer@l
lwz r4, sample_count(r0) # Number of samples
li r5, 0                # Sample index

load_samples:
    slwi r6, r5, 1      # Convert index to byte offset
    lhzx r7, r3, r6     # Load 16-bit sample
    
    # Convert unsigned to signed if needed
    cmpwi r7, 32768     # Check if >= 32768
    blt positive_sample
    subi r7, r7, 65536  # Convert to signed 16-bit
    
positive_sample:
    # Process sample in r7
    bl process_audio_sample
    
    addi r5, r5, 1      # Next sample
    cmpw r5, r4         # Check if done
    blt load_samples    # Continue if more samples

Image Pixel Data (16-bit RGB565)

# Load 16-bit RGB565 pixel data
lis r3, image_data@ha
addi r3, r3, image_data@l
lwz r4, image_width(r0)
lwz r5, image_height(r0)
li r6, 0                # Y coordinate
li r7, 0                # X coordinate

load_pixels:
    mullw r8, r6, r4    # Calculate row offset
    add r8, r8, r7      # Add column offset
    slwi r8, r8, 1      # Convert to byte offset
    lhzx r9, r3, r8     # Load RGB565 pixel
    
    # Extract color components
    rlwinm r10, r9, 0, 27, 31   # Extract blue (bits 0-4)
    rlwinm r11, r9, 21, 26, 31  # Extract green (bits 5-10)
    rlwinm r12, r9, 16, 27, 31  # Extract red (bits 11-15)
    
    # Process pixel components
    bl process_pixel    # Pass r10=blue, r11=green, r12=red
    
    # Advance to next pixel
    addi r7, r7, 1      # Next column
    cmpw r7, r4         # Check end of row
    blt load_pixels     # Continue row
    
    li r7, 0            # Reset column
    addi r6, r6, 1      # Next row
    cmpw r6, r5         # Check end of image
    blt load_pixels     # Continue image

File System Directory Entry

# Parse FAT directory entry (16-bit fields)
lis r3, dir_entry@ha
addi r3, r3, dir_entry@l

# FAT directory entry structure (simplified)
lhz r4, 0(r3)           # Load first cluster (low 16 bits)
lhz r5, 20(r3)          # Load first cluster (high 16 bits)
lhz r6, 22(r3)          # Load creation time
lhz r7, 24(r3)          # Load creation date
lhz r8, 26(r3)          # Load last access date
lhz r9, 28(r3)          # Load last write time
lhz r10, 30(r3)         # Load last write date

# Combine high and low cluster numbers
slwi r5, r5, 16         # Shift high part to upper 16 bits
or r11, r4, r5          # Combine into full 32-bit cluster number

Graphics Texture Coordinate Loading

# Load texture coordinates (16-bit fixed point)
lis r3, texture_coords@ha
addi r3, r3, texture_coords@l
li r4, 10               # Vertex index
slwi r5, r4, 2          # 4 bytes per vertex (2 coordinates)
add r6, r3, r5          # Vertex coordinate address

lhz r7, 0(r6)           # Load U coordinate (16-bit)
lhz r8, 2(r6)           # Load V coordinate (16-bit)

# Convert from fixed point to floating point
# Assuming format is 8.8 fixed point
li r9, 256              # Scale factor
stw r7, temp_u(r1)      # Store to memory
stw r8, temp_v(r1)
lfs f1, temp_u(r1)      # Load as float
lfs f2, temp_v(r1)
li r10, 256
stw r10, scale(r1)
lfs f3, scale(r1)
fdivs f1, f1, f3        # Convert to float
fdivs f2, f2, f3

Configuration Data Loading

# Load device configuration values (16-bit)
lis r3, config_block@ha
addi r3, r3, config_block@l

lhz r4, CFG_DEVICE_ID(r3)    # Load device ID
lhz r5, CFG_REVISION(r3)     # Load revision number  
lhz r6, CFG_CAPABILITIES(r3) # Load capability flags
lhz r7, CFG_MAX_SPEED(r3)    # Load maximum speed
lhz r8, CFG_BUFFER_SIZE(r3)  # Load buffer size

# Validate configuration
lis r9, EXPECTED_DEVICE_ID@ha
ori r9, r9, EXPECTED_DEVICE_ID@l
cmpw r4, r9             # Check device ID
bne wrong_device        # Branch if mismatch

cmpwi r5, MIN_REVISION  # Check minimum revision
blt unsupported_revision # Branch if too old

Compression Dictionary Loading

# Load compression dictionary entries (16-bit indices)
lis r3, compression_dict@ha
addi r3, r3, compression_dict@l
lis r4, input_stream@ha
addi r4, r4, input_stream@l

decompress_loop:
    lhz r5, 0(r4)       # Load dictionary index (16-bit)
    cmpwi r5, 0         # Check for end marker
    beq decompress_done
    
    # Look up dictionary entry
    slwi r6, r5, 1      # Convert to byte offset
    lhzx r7, r3, r6     # Load dictionary value
    
    # Output decompressed value
    stb r7, output_buffer(r8)
    addi r8, r8, 1      # Advance output pointer
    
    addi r4, r4, 2      # Advance input pointer
    b decompress_loop

decompress_done:

MIDI Note Data

# Load MIDI note information (16-bit values)
lis r3, midi_sequence@ha
addi r3, r3, midi_sequence@l
li r4, 0                # Time offset

play_sequence:
    lhz r5, 0(r3)       # Load delta time (16-bit)
    lhz r6, 2(r3)       # Load note data (pitch + velocity)
    
    add r4, r4, r5      # Update current time
    
    # Extract note information
    rlwinm r7, r6, 0, 24, 31   # Extract note number (bits 0-7)
    rlwinm r8, r6, 24, 24, 31  # Extract velocity (bits 8-15)
    
    cmpwi r8, 0         # Check for note off
    beq note_off
    
    # Note on
    bl play_note        # Pass r7=note, r8=velocity, r4=time
    b next_event

note_off:
    bl stop_note        # Pass r7=note, r4=time

next_event:
    addi r3, r3, 4      # Move to next event
    lhz r9, 0(r3)       # Check for end marker
    cmpwi r9, 0xFFFF
    bne play_sequence   # Continue if not end

Database Record Field Access

# Access 16-bit fields in database record
lis r3, record_buffer@ha
addi r3, r3, record_buffer@l

lhz r4, FIELD_ID(r3)        # Load record ID (16-bit)
lhz r5, FIELD_TYPE(r3)      # Load record type (16-bit)
lhz r6, FIELD_FLAGS(r3)     # Load flags (16-bit)
lhz r7, FIELD_SIZE(r3)      # Load data size (16-bit)
lhz r8, FIELD_CHECKSUM(r3)  # Load checksum (16-bit)

# Validate record
cmpwi r4, 0             # Check for valid ID
beq invalid_record
cmpwi r7, MAX_RECORD_SIZE # Check size limit
bgt record_too_large

# Check record type
cmpwi r5, TYPE_USER_DATA
beq process_user_data
cmpwi r5, TYPE_SYSTEM_DATA  
beq process_system_data
b unknown_record_type

Network Port Scanning

# Scan network services on different ports
lis r3, port_list@ha
addi r3, r3, port_list@l
lwz r4, port_count(r0)  # Number of ports to scan
li r5, 0                # Port index

scan_ports:
    slwi r6, r5, 1      # Convert to byte offset
    lhzx r7, r3, r6     # Load port number (16-bit)
    
    # Attempt connection to port
    mr r3, r7           # Pass port number
    bl attempt_connection
    cmpwi r3, 0         # Check connection result
    beq connection_failed
    
    # Port is open
    mr r3, r7           # Pass port number
    bl identify_service # Identify service on port
    
connection_failed:
    addi r5, r5, 1      # Next port
    cmpw r5, r4         # Check if done
    blt scan_ports      # Continue scanning

Related Instructions

lhzu, lhzx, lhzux, lha, sth, lbz, lwz

Back to Index