Table of contents

p6as

p6as is a microcode assembler for Intel P6 architecture processors (Pentium Pro, Pentium II, Pentium III, Pentium M, Core, Core 2), part of p6microcode-tools. It compiles Intel P6 microcode assembly language into 80-bit microinstructions through a two-pass process:

Pass 0: Collect label definitions and store assembly lines

Pass 1: Assemble instructions and resolve labels

p6as arguments

p6as [-h] [-t type] [-L label_spec]

Command Line Options

argument -h - Show help message and exit

argument -t type - Set CPU type. Valid types: pentiumpro, pentium2, pentium3, pentiumm, core, core2

argument -L label_spec - Add label or load labels from file

Format: LABEL=addr (e.g., -L my_label=0x1234)

Or: @filename to load labels from a file (e.g., -L @labels.lbl)

argument input_file - Assembly file to process. Use '-' for stdin

Examples

p6as -t pentium3 microcode.asm > output.triad
p6as -L entry_point=0x100 -L @common_labels.lbl code.asm
p6as - < input.asm > output.triad

p6as source code syntax

Comments

p6as supports C-style block comments and line comments that start with #, //, or ;

# This is a line comment
// This is also a line comment
; This is also a line comment

/* This is a
block comment */

Address Specification

Instructions can have explicit addresses or use implicit addressing:

Explicit Addressing

UROM_XXXX instruction

The address must be in format UROM_ followed by exactly 4 hexadecimal digits.

Implicit Addressing

If no UROM_ prefix is present, the assembler uses the current address counter, which auto-increments. The counter can be set using the .org directive.

Labels

Labels are defined with a colon and must contain only alphanumeric characters and underscores:

my_label:
instruction

another_label: instruction_on_same_line

Labels can be referenced in branch targets and .write_creg_offsets directives.

For more information on assembly syntax, see uops page

p6as directives

All directives start with a dot (.).

Conditional Assembly Directives

.if

Start a conditional block based on a boolean condition.

Syntax:

.if condition

Arguments:

condition - Must be: 0, 1, false, or true

Example:

.if 1
; This code is assembled
.endif

.if 0
; This code is skipped
.endif

.ifdef

Start a conditional block if a label/symbol is defined.

Syntax: .ifdef symbol_name

Arguments: symbol_name - Label to check for existence (label must already exist, i.e. be defined from commandline -L argument (or via labelfile), or BEFORE .ifdef

Example:

.ifdef FEATURE_ENABLED
; Code if FEATURE_ENABLED label exists
.endif

.else

Toggle the condition state within a conditional block.

Syntax:

.else

Example:

.if 0
; This is skipped
.else
; This is assembled
.endif

.endif

End a conditional block.

Syntax:

.endif

Notes:

Conditional directives can be nested up to 32 levels deep

All .if/.ifdef blocks must be closed with .endif

Conditions affect all subsequent lines including other directives

Assembler directives

.cputype

.tripletalign

.org

Sets the current address for subsequent instructions.

Syntax:

.org address

Arguments:

address - Hexadecimal (with or without 0x prefix) or decimal value

Note: Using .org when .utripletbits is pending will cause an error.

.utripletbits

Specifies unknown triplet bits for the current address (must be aligned to address & 3 == 0).

Syntax:

.utripletbits binary_string

Arguments:

binary_string - String of '0' and '1' characters

Example:

.utripletbits 0101010101010101

Note: This directive must be used at addresses aligned to 4-byte boundaries (address & 3 == 0).

.end

Stops further processing of the input file. Useful for placing additional data or comments after the assembly code.

Syntax:

.end

Directives passed to p6scrambler / p6patchtool

These directives are passed through unchanged to downstream tools in the processing pipeline.

.write_creg

Specifies a CRBUS register write operation.

Syntax:

.write_creg register mask value

Arguments:

register - 32-bit register address (decimal or hex with 0x prefix)

mask - 32-bit mask value

value - 32-bit value to write

Example:

.write_creg 0x1B2 0x00000000 0x003E0035

Maximum: 128 .write_creg directives per file

.write_creg_offsets

Similar to .write_creg but for MATCH-PATCH CRBUS registers. The mask field is always zero, and two 16-bit offsets are concatenated into the value field.

Syntax:

.write_creg_offsets register offset1 offset2

Arguments:

register - 32-bit register address (decimal or hex with 0x prefix)

offset1 - 16-bit offset (numeric value or label reference)

offset2 - 16-bit offset (numeric value or label reference)

Example:

.write_creg_offsets 0x200 0x1000 0x2000
.write_creg_offsets 0x200 start_label end_label

Note: offset1 becomes bits [31:16] and offset2 becomes bits [15:0] of the value field.

.header_ver

Specifies the header version field.

Syntax:

.header_ver value

update_rev

Argument: numeric 32-bit value

date_bcd

Argument: numeric 32-bit value

proc_sig

Argument: numeric 32-bit value

checksum

Argument: numeric 32-bit value

loader_rev

Argument: numeric 32-bit value

proc_flags

Argument: numeric 32-bit value

data_size

Argument: numeric 32-bit value

total_size

Argument: numeric 32-bit value

key_seed

Argument: numeric 32-bit value

unknown

Argument: numeric 32-bit value

update_rev2

Argument: numeric 32-bit value


The author is not affiliated with, endorsed by, or sponsored by Intel Corporation or its affiliates. All trademarks, including but not limited to Intel, Pentium, and any other registered or unregistered marks mentioned herein, are the property of their respective owners. Their use in this context is solely for descriptive and informational purposes and constitutes nominative fair use under applicable trademark laws.