For programming and/or microarchitecture questions about the 16-bit x86 Intel CPUs, including the 8088, 8086, and later chips running in 16-bit mode.
x86-16 refers to the 16-bit family of instruction set architectures (ISAs) based on the Intel 8086 CPU. This processor was designed by Intel in the mid-1970s, and gave rise to the x86 architecture.
See the x86 tag wiki for links to x86 ISA and assembly-language programming resources (mostly aimed at modern 32-bit and 64-bit implementations).
The 8086 uses the same instruction set as later x86 processors, but it is limited to 16-bit mode and lacks support for instructions added with 186, 286, 386 (or later). This means that extremely useful instructions like movzx
are unavailable, so many operations require moving data into ax
for use with instructions that have it as an implicit operand. The 16-bit implementation of x86 is also limited with respect to which registers can be used in addressing modes. This addressing limitation persists in modern CPUs running in 16-bit mode, because the machine-code format is the same.
The 8088 is a derivative of the 8086. The 8088 is identical in functionality to the 8086 and is fully 16-bit internally, but it has an 8-bit external data bus (instead of the 8086's 16-bit external data bus). In terms of programming, there are no salient differences between the 8088 and 8086, so these are combined under a single tag. Feel free to mention which specific chip you're targeting in the body and/or title of the question, though.
This tag is also appropriate for questions about non-Intel CPUs that use the same instruction set as the 8086, including the NEC v20 and v30, AMD 8086 clones, etc. There are also some modern microcontrollers that use simple 8086 cores.
Note that, while it will run on modern x86 CPUs, code that uses only the 16-bit instructions (as would be supported on an 8086) is not usually considered good or efficient code.
However, there remains much interest in writing 16-bit code for dos emulators (such as DOSBox and emu8086) and real vintage hardware, both from beginners and enthusiasts. retrocomputing.SE has an 8086 tag, but unless you're asking about actual ancient hardware, Stack Overflow is the right place for questions about 16-bit bootloaders, kernels, and DOS executables. Retrocomputing is mostly about even older systems, like 8-bit micros.
- 8086 assembler tutorial for beginners - emu8086 (MASM/TASM style) 16-bit only, but starts out with some nice intro stuff about hex vs. decimal, what assembly language is, what registers are and how memory is addressed, and how to look at memory in the debugger, before jumping into how specific instructions work.
- Instruction set reference, including when introduced (8086, 186, 286, 386, etc.) Forked from an old version of the NASM appendix, keeping the English descriptions but fixing mistakes in which generation instructions appeared.
- General Tips for Bootloader Development
- working example of a bootloader that loads a "kernel" and calls a C
main
function in it, in 32-bit protected mode. And instructions on how to build and link it with NASM,gcc -m32
, andld
. And run it on QEMU.
Debuggers
Single-stepping in a debugger and looking at registers is essential. Trying to write a program without one is like trying to build a robot blindfolded. It's very much worth the time to learn to use one. For 32/64-bit mode under a modern OS, see the debugging section at the bottom of the x86 tag wiki.
Under DOS:
- @ecm's lDebug, based on
debug.com
from FreeDOS. - Turbo Debugger is widely recommended, and maybe can be found for free
debug.exe
/debug.com
in MS-DOS or FreeDOS is an option, although classic MS-DOS DEBUG is pretty terrible to actually program in, not having labels, only numeric addresses for jump targets and so on!
Full system (for bootloaders, or maybe DOS programs)
- Bochs is usually the gold standard, with a built-in debugger that's aware of segmentation. Manual. Note that it's an optional config feature; some builds might not come with it enabled. It's great for debugging the switch to 32-bit protected mode, and 64-bit mode. It can parse and dump your GDT and page tables, to help you spot mistakes in what you put there, and it knows what mode the CPU is in so it will disassemble in the right mode to match execution, helping you catch mistakes where code was assembled for the wrong bitness.
- QEMU: can act as a remote for GDB. GDB doesn't know about segmentation so this isn't ideal for real mode or during the switch to protected mode.
- DOSBox: There's a DOSBox-X fork with a built-in debugger, and the mainline DOSBox apparently also has a debugger built-in. (Curses-based text UI)
Related Tags:
- x86 (for the x86 in general, including 32-bit and 64-bit. Lots of good stuff in the tag wiki, including some 16-bit links)
- x86-64 (for stuff specifically about the 64-bit extensions to the x86 ISA)
- x87 (for the legacy numeric coprocessor—aka floating point unit, as opposed to the SSE/SSE2 FPU)
- assembly (for programs written in assembly language of any kind, including x86, MIPS, ARM, and toy architectures like LC-3)
- dos (for programs targeting DOS and/or questions about DOS APIs)
- emu8086 (for questions specifically about the EMU8086 emulator package, often used by students)