Est. 1978 Advanced

Assembler (Intel 8086)

The 16-bit assembly language Intel defined for the 8086 in 1978 — ASM86, a deliberately strongly typed assembler with segmented addressing, PTR overrides and user-definable codemacros — and the source-level bridge that carried 8080 programs into the x86 era.

Created by Intel Corporation; instruction set architecture by Stephen P. Morse

Paradigm Assembly, Imperative, Low-level
Typing Untyped at the machine level; ASM86 itself is, in Intel's words, "strongly typed" at assembly time
First Appeared 1978
Latest Version No versioned language standard. Intel's own line ran from the MCS-86 Assembly Language Reference Manual (9800640, copyright 1978) to the ASM86 Language Reference Manual (121703-003, March 1985); third-party assemblers such as NASM still assemble the same 16-bit instruction set today

Assembler (Intel 8086) is the assembly language Intel defined in 1978 for its first 16-bit microprocessor. Intel called it ASM86 and documented it in the MCS-86 Assembly Language Reference Manual, order number 9800640, which carries a 1978 copyright. It is the point at which the 8-bit Intel line — 8008, 8080, 8085 — turned into the x86 architecture that still runs most desktops and servers. Almost everything a modern x86 programmer recognises is already present in the 1978 manual: MOV, PUSH, JMP, the AX/BX/CX/DX register file, the REP-prefixed string instructions, segment registers, the PTR override. What is not present is the flat address space; that arrived with the 386 seven years later, and much of what distinguishes 8086 assembly from later x86 assembly is the machinery for living without it.

History and Origins

A stopgap that outlived everything around it

The 8086 project started in May 1976. Intel’s flagship effort at the time was the iAPX 432, an ambitious 32-bit object-oriented processor that was running badly late, and the 8086 was commissioned as a temporary answer to the 16-bit parts that Motorola, Zilog and National Semiconductor were about to ship. Stephen P. Morse, the architect, later recalled that this was precisely what gave him room to work: “Because nobody expected the design to live long, no barriers were placed in my way, and I was free to do what I wanted.” He also described the methodological shift that made the result unusual for its era — “For the first time, we were going to look at processor features from a software perspective,” asking what features would make software more efficient rather than what would fit in the available die area.

The chip was released on 8 June 1978. It was built in nMOS at roughly 3 μm with on the order of 29,000 transistor sites (about 20,000 of them active logic, the rest ROM and PLA), packaged in a 40-pin DIP, and initially specified at 5 MHz; later HMOS parts reached 8 and 10 MHz. The iAPX 432 went nowhere. The stopgap became the architecture.

The compatibility constraint that shaped the language

Intel’s management set a condition on the design: software written for the 8080 had to be able to move forward. The 8086 is not binary compatible with the 8080 — no 8080 object code runs on it — but it was deliberately made source compatible in a mechanical sense, and Intel shipped the tool to prove it. CONV86, documented in manual 9800642 (copyright 1979), reads an error-free 8080/8085 assembly source file and writes an 8086 assembly source file. Its register mapping is the clearest surviving fingerprint of that constraint:

8080/80858086
AAL
B, CCH, CL
D, EDH, DL
H, LBH, BL

That is why the 8086’s byte registers are addressable as halves of the word registers at all, and why BX — not AX — is the register the 8086 will use as a memory pointer: BX is where HL landed.

Intel was honest about the limits of the exercise. The converter manual devotes a section to what conversion does not preserve, including program execution time and software timing delays, and CONV86 emits “caution messages” flagging constructs that need manual editing. Intel’s own manual even asks, in a section heading, “What Advantage Is There in Rewriting Programs in 8086 Assembly Language Rather Than Converting?”

The Language

An assembler that type-checks

The most distinctive feature of ASM86 as Intel defined it is not an instruction. It is the claim the 1978 manual makes in its first chapter:

The 8086 assembly language is “strongly typed”. This means it performs extensive checks on your variables and labels… The assembler makes sure that each use of a symbol in later instructions conforms to the usage defined for that symbol when it was declared.

A variable declared with DB has type byte, one declared with DW has type word, one declared with DD has type doubleword, and the assembler refuses instructions that use them inconsistently. This is why PTR exists: MOV BYTE PTR [BX], 0 is not decoration but the override that tells a type-checking assembler you meant it. The companion operators SEG, TYPE, OFFSET, THIS, LENGTH, SIZE and WIDTH all exist to interrogate or construct those attributes at assembly time. Intel’s stated rationale was defensive: the checks are “an extra safeguard against unintended or meaningless code arising from errors of omission or inconsistency.”

The register model

RegisterWritten asRole
AXAX / AH, ALAccumulator; implicit in MUL, DIV, IN, OUT, the string and BCD instructions
BXBX / BH, BLBase register — the only general register besides BP, SI and DI usable in [...] addressing
CXCX / CH, CLCount for REP-prefixed strings, LOOP and variable shifts (via CL)
DXDX / DH, DLHigh half of MUL/DIV operands; indirect I/O port number
SI, DISI, DISource and destination indexes; the implicit operands of the string instructions
BP, SPBP, SPFrame pointer and stack pointer, both defaulting to the stack segment
CS, DS, SS, ESCS, DS, SS, ESCode, data, stack and extra segment bases
IP, FLAGSInstruction pointer and status flags, not directly addressable as operands

Sixteen-bit arithmetic that the 8080 had to synthesise from carry chains became a single ALU operation, and MUL, IMUL, DIV and IDIV exist in hardware for the first time in the family — though they are microcoded and slow, quoted in Intel’s timing tables at roughly 70-160 clocks for multiply and 80-190 for divide depending on operand size and data, versus 2-4 clocks for a register-to-register MOV or ALU operation. Those are the manufacturer’s published instruction timings for the original part, not measured benchmark figures, and they are best-case numbers that ignore prefetch state and instruction alignment.

Segments, and the 20-bit address

The 8086 has 16-bit registers but a 20-bit address bus. A physical address is formed by shifting a segment register left four bits and adding a 16-bit offset, giving a 1 MB space carved into overlapping 64 KB windows. Every memory reference therefore carries an implicit segment: instruction fetches go through CS, stack operations and anything based on BP through SS, most data through DS, and string destinations through ES.

The language is built around making that implicit choice explicit and checkable. SEGMENT/ENDS declare a segment with an alignment (BYTE, WORD, PARA, PAGE, INPAGE) and a combination type (PUBLIC, COMMON, STACK, MEMORY, AT). GROUP collects segments that will share a base. And ASSUME — the directive with no counterpart in flat-model assembly — tells the assembler which segment register it may presume points at which segment, so that it can decide for itself whether a reference needs a segment-override prefix byte. ASSUME NOTHING withdraws that presumption. Get ASSUME wrong and the assembler will silently compute addresses against a segment register that does not hold what you think it holds; this is the classic 8086 assembly bug, and it has no analogue on a 386 in flat mode.

Directives and expressions

Beyond the segment machinery, the 1978 language provides DB/DW/DD with the DUP replication facility and ? for uninitialised storage, RECORD for bit-field definitions, PROC/ENDP with NEAR and FAR distance attributes, LABEL, EQU, PURGE, ORG, and the module-linkage set NAME, PUBLIC, EXTRN and END. Assembly-time expressions have a full operator hierarchy: additive operators, the variable-manipulation operators above, SHORT, the logical AND/OR/XOR/NOT, the relational EQ/NE/LT/LE/GT/GE, multiplicative and shift operators, and the byte-isolation HIGH and LOW inherited from the 8080 assembler.

Codemacros

One genuinely unusual feature of Intel’s assembler is that the instruction set is not hard-wired into it. Chapter 7 of the 1978 manual documents codemacros: definitions that specify how a mnemonic, given operands matching certain specifiers, is to be encoded into bytes. The primitives are things like SEGFIX and NOSEGFIX (emit or suppress a segment-override prefix), MODRM (build the addressing-mode byte), RELB/RELW (emit a relative displacement) and DB/DW/DD. Appendix A of the manual prints the codemacros for the entire 8086 instruction set — the assembler’s own instruction definitions, written in the user-accessible notation. A programmer could extend the mnemonic set the same way, which is how coprocessor instructions could be bolted on.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
; ASM86-style source in Intel's original idiom
DATA    SEGMENT PUBLIC
MSG     DB      'HELLO', 0DH, 0AH
MSGLEN  EQU     $ - MSG
DATA    ENDS

CODE    SEGMENT PUBLIC
        ASSUME  CS:CODE, DS:DATA
PRINT   PROC    NEAR
        MOV     CX, MSGLEN      ; REP count
        MOV     SI, OFFSET MSG  ; OFFSET yields the 16-bit offset within DATA
NEXT:   LODSB                   ; AL <- DS:[SI], SI advanced per the direction flag
        CALL    PUTCHAR
        LOOP    NEXT
        RET
PRINT   ENDP
CODE    ENDS
        END

Beyond Intel’s Assembler

Intel’s ASM86 ran on Intellec development systems under ISIS-II, which put it out of reach of most people who ended up writing 8086 code. The language spread through other implementations of the same mnemonics:

  • 86-DOS. Tim Paterson wrote what became MS-DOS in 8086 assembly starting in April 1980, using his own assembler; the operating system and the tools to build it grew up together.
  • MASM. Microsoft’s Macro Assembler appeared in 1981, sold both directly and as IBM’s OEM-branded IBM Macro Assembler (December 1981). According to the commonly cited MASM version list, successive releases tracked the hardware — 8087 support in 1.10 (1982), 8087 emulation in 1.25 (1983), 186/286/287 instructions in 2.00 (1984), 286 protected-mode instructions in 3.00 (1984) and 386 support in 5.00 (August 1987), the release that also introduced the simplified segment directives. Other secondary accounts place 286 support a version later, at 4.0 (October 1985), so the intermediate version-to-feature mapping should be treated as approximate. MASM’s .MODEL/.CODE/.DATA directives and its ASSUME behaviour are recognisably descended from Intel’s design.
  • Borland’s Turbo Assembler (TASM), released in the late 1980s, offered a MASM-compatible mode alongside its own IDEAL syntax, which tightened exactly the type and segment rules that MASM had loosened.
  • NASM, first released as version 0.90 in October 1996 by Simon Tatham and Julian Hall, is free, portable, and deliberately more regular in its treatment of operand sizes and memory references. It remains one of the most widely used ways to assemble 16-bit 8086 code today.

These are all the same language in the sense that matters — the same mnemonics against the same instruction encodings — but they differ substantially in directives, macro facilities, and how much type checking they impose. Code written for one rarely assembles unmodified under another without attention to the segment and size directives.

Evolution

The 8086 language was extended rather than replaced. The 8088 (1979) is the identical programming model over a narrower bus. The 8087 (announced 1980) added an 80-bit floating-point stack machine whose instructions ride in the 8086’s ESC opcode space, so FADD and FMUL became part of the same assembly source files. The 80186 added a handful of convenience instructions — PUSHA, POPA, ENTER, LEAVE, immediate-form IMUL, block I/O — and the 80286 added protected mode and its supervisory instructions. None of this invalidated an 8086 program; the family’s compatibility discipline has been maintained ever since, which is why a correctly written 1978 MOV/ADD/JNZ sequence still assembles and still executes on hardware nearly five decades later.

The one discontinuity is the address space. The 386 of 1985 widened the registers to 32 bits and introduced a flat model that made segmentation largely vestigial, and 64-bit long mode removed most of what remained. ASSUME, GROUP, NEAR/FAR and the segment-override prefix are the parts of 8086 assembly that a modern x86 programmer will never have used.

Current Relevance

Nobody starts new commercial projects in 16-bit 8086 assembly, which is why the encyclopedia lists the language as historical. But it remains unusually present for a language of its age:

  • Every x86 processor still boots into it. An x86 CPU begins execution in real-address mode, with 8086 semantics and segmented 20-bit addressing, and the firmware executes 8086-compatible instructions before switching to protected or long mode. No shipping x86 processor has removed that mode.
  • It is a standard teaching vehicle. Undergraduate computer-architecture and microprocessor courses still use 8086 assembly, usually under an emulator, because the register model is small enough to hold in your head and the segmentation is pedagogically instructive.
  • Retrocomputing and DOS preservation. The DOS software base is 8086-family machine code, and disassembling, patching and reimplementing it is a large and active hobby. NASM, and emulators for the original hardware, keep the toolchain alive.
  • The documentation survives intact. Intel’s 1978 and 1985 manuals, the CONV86 converter manual and the full instruction reference are scanned and freely readable at bitsavers and the Internet Archive, which is more than can be said for many languages fifty years younger.

Why It Matters

The 8086 assembly language is where a particular set of accidents became permanent. The register naming, the byte/word register aliasing, the choice of BX as the pointer register, the accumulator’s privileged role in multiply and I/O, the string instructions with their direction flag and REP prefix — all of these were shaped by the requirement that 8080 assembly source convert mechanically, a constraint imposed on a chip nobody at Intel expected to last. Every one of them is still visible in the instruction set that runs the majority of the world’s servers.

It is also a reminder that assemblers can be opinionated. Intel’s ASM86 type-checks variables, tracks segment attributes across ASSUME declarations, and defines its own instruction encodings in a user-visible macro notation. That is a considerably more elaborate design than “one mnemonic, one opcode”, and it was a deliberate response to a machine whose addressing model was easy to get quietly wrong. The PTR keyword that x86 programmers still type every day is a surviving piece of a 1978 argument about whether an assembler should be allowed to tell you that you are wrong.

Timeline

1976
Intel starts the 8086 project in May as a stopgap while the ambitious 32-bit iAPX 432 slips. Stephen P. Morse is made sole architect of the instruction set, with a management requirement that 8080 assembly source be mechanically convertible to the new machine
1978
Intel releases the 8086 on 8 June: a 16-bit processor in a 40-pin DIP, built on a roughly 3 micron nMOS process, with a 20-bit address bus giving a 1 MB physical address space. The first part is rated at 5 MHz
1978
Intel publishes the MCS-86 Assembly Language Reference Manual, order number 9800640, carrying a 1978 copyright. It defines ASM86: roughly 100 mnemonics in six classes from which the assembler can generate "over 3,800 distinct machine-instructions"
1979
Intel ships CONV86, the MCS-86 Assembly Language Converter, documented in manual 9800642 (copyright 1979). It reads error-free 8080/8085 assembly source and emits 8086 assembly source, mapping A to AL, B and C to CH and CL, D and E to DH and DL, and H and L to BH and BL
1979
The 8088 follows — the same instruction set and the same assembly language behind an external 8-bit data bus, which lets system designers reuse cheap 8080-family support chips
1980
The 8087 numeric coprocessor is announced, adding a floating-point register stack and its own mnemonics to the same assembly language via the ESC escape mechanism
1980
Tim Paterson begins QDOS at Seattle Computer Products in April, written entirely in 8086 assembly language. Version 0.10 is running by July and the product is renamed 86-DOS by August; in December Microsoft buys a non-exclusive licence to it (the signed agreement is dated January 1981)
1981
IBM launches the IBM PC on 12 August around the 8088. The IBM Macro Assembler ships in December and Microsoft releases MASM 1.00, putting an 8086-family assembler on desks far outside Intel's development-system customers
1982
The 80186 and 80286 arrive, both introduced in early 1982. They extend the 8086 language rather than replace it: every 8086 mnemonic remains valid, and the 286 adds protected mode on top
1985
Intel issues the ASM86 Language Reference Manual, order number 121703-003, dated March 1985 with a 1981-1983 copyright line — the mature form of Intel's own 8086 assembly language documentation
1987
IBM ships the PS/2 Model 30 (2 April) and Model 25 (4 August), both built on an 8 MHz 8086, keeping the original 16-bit part in mainstream production nearly a decade after its debut
1996
NASM 0.90 is released in October by Simon Tatham and Julian Hall. Free, portable and Intel-syntax, it becomes a common way to assemble 16-bit 8086 code long after Intel's own toolchain disappears
1998
Intel is generally reported to have ended 8086 production in 1998, after roughly two decades, though CMOS 80C86 variants and second-source clones from NEC, AMD, Harris, OKI, Siemens and others had long since spread the part into embedded systems
2018
Intel marks the 40th anniversary of the 8086 on 5 June with the limited-edition Core i7-8086K — a processor that, like every x86 part before it, still begins execution in a 16-bit mode that speaks the 1978 instruction set

Notable Uses & Legacy

86-DOS and MS-DOS (Seattle Computer Products / Microsoft, 1980-)

Tim Paterson wrote 86-DOS entirely in 8086 assembly language, starting in April 1980 and reaching version 0.10 by that July. Microsoft bought a non-exclusive licence in December 1980 (the signed agreement is dated January 1981), and the assembly-language lineage ran on through PC DOS and MS-DOS, including the practice of writing whole utilities and the kernel itself in ASM.

IBM PC and its software ecosystem (1981-)

The IBM PC of 12 August 1981 used the 8088, which programs in the identical assembly language. The IBM Macro Assembler (December 1981) and Microsoft MASM 1.00 made 8086 assembly the lingua franca for BIOS code, device drivers, terminate-and-stay-resident utilities and the performance-critical inner loops of early PC applications.

IBM PS/2 Models 25 and 30 (1987)

IBM's entry-level PS/2 machines, announced 2 April and 4 August 1987, both ran a genuine 8086 at 8 MHz rather than the 8088 of the original PC. They put the 1978 part — and hand-written 8086 assembly in their ROM and drivers — into offices and schools well into the 1990s.

Portable and embedded systems built on the CMOS 80C86

The fully static CMOS 80C86 was adopted for battery-powered machines where the nMOS original could not go, including the Toshiba T1200, the HP 110 and the GRiDPad. Low-power 8086-compatible parts in CMOS remained in embedded use long after the desktop market had moved on.

Intel development systems and CONV86 migrations (1978-1980s)

Intel's own Intellec/ISIS-II systems hosted ASM86 alongside PL/M-86, and CONV86 gave 8080 and 8085 shops a mechanical path forward. Intel was candid that conversion was not free: converted code preserves function, not timing, and the converter emitted caution messages wherever hand-editing was required.

Lunar Prospector (NASA, 1998-1999)

The Lunar Prospector orbiter is reported to have used an 80C86 in its flight computer, placing the CMOS descendant of the 1978 design in lunar orbit twenty years after the chip's introduction. The attribution is widely repeated but rests on secondary sources rather than a mission document we could verify directly.

Language Influence

Running Today

Run examples using the official Docker image:

docker pull
Last updated: