Questions tagged [x86-16]

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 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 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 emulators (such as DOSBox and ) 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.



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:

  • (for the x86 in general, including 32-bit and 64-bit. Lots of good stuff in the tag wiki, including some 16-bit links)
  • (for stuff specifically about the 64-bit extensions to the x86 ISA)
  • (for the legacy numeric coprocessor—aka floating point unit, as opposed to the SSE/SSE2 FPU)
  • (for programs written in assembly language of any kind, including x86, MIPS, ARM, and toy architectures like LC-3)
  • (for programs targeting DOS and/or questions about DOS APIs)
  • (for questions specifically about the EMU8086 emulator package, often used by students)
2894 questions
10
votes
6 answers

How to set 1 second time delay at assembly language 8086

My problem is that I have written a code that is supposed to output a result into a set of LEDs connected to the parallel port. When I ran the code it pretty much did nothing. My instructor told me that the code ran too fast that my eyes did not see…
Jer Yango
  • 582
  • 2
  • 8
  • 22
10
votes
2 answers

Why doesn't MS-DOS initialize the DS and ES registers?

Why does the initialization of the DS and ES registers has to be done manually by the programmer? For example: MOV AX, DTSEG MOV DS, AX On the other hand, the CS and SS registers are initialized by the operating system (in MS-DOS). Why is this…
mohammad mahed
  • 511
  • 2
  • 6
  • 11
9
votes
4 answers

How many registers are there in 8086/8088?

I took Computer Architecture course and I understood that processor has 32 registers each of 32 bit. Now I am studying computer architecture course in which I read that 8086 has 8 registers only. But the book I read and this website shows many…
user379888
9
votes
4 answers

Why does CMP (compare) sometimes sets a Carry Flag in 8086 assembly?

I've been reading around and with the 8086 Instruction Set, it says that a CMP (compare) can set the Carry Flag. I understand that a compare subtracts two operands but I was wondering if anyone can provide an example when that is the case. I just…
faul
  • 227
  • 2
  • 4
  • 13
9
votes
1 answer

Segmented far pointer allocation in 16bit x86 MS-DOS real mode

I'm trying to get my head around programming real mode MS-DOS in C. Using some old books on game programming as a starting point. The source code in the book is written for Microsoft C, but I'm trying to get it to compile under OpenWatcom v2. I've…
IronPug
  • 123
  • 4
9
votes
1 answer

Displaying characters with DOS or BIOS

Looking through Ralph Brown's interrupt list, I discovered that there are many different ways to output text characters to the screen. The ROM BIOS API offers these functions: AH=09h – Write Character and Attribute at Cursor Position AH=0Ah –…
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
9
votes
4 answers

What does it mean by "MOV AH, 4CH" in assembly language?

Most of the assembly code is terminate by the following instructions MOV AH, 4CH INT 21H What does it mean by "MOV AH, 4CH" ?
Shams Nahid
  • 6,239
  • 8
  • 28
  • 39
9
votes
5 answers

Print integer to console in x86 assembly

When I add two values in 16 bit assembly, what is the best way to print the result to console? At the moment I have this code: ;;---CODE START---;; mov ax, 1 ;put 1 into ax add ax, 2 ; add 2 to ax current value mov ah,2 ; 2 is the function…
pacman.
  • 217
  • 1
  • 2
  • 9
9
votes
1 answer

Error: Operation size not specified - NASM

I'm working in 16 bit NASM assembly having an issue where my code won't build. The error happens on all the MOV lines here: section .bss x_coord RESB 8 ; [x_coord] is the head, [x_coord+2] is the next cell, etc. y_coord RESB 8 ; Same here …
Nat
  • 890
  • 3
  • 11
  • 23
9
votes
2 answers

What happens in the x86 architecture when an interrupt occurs?

I'm studying x86 and Real Time Systems, and I have a question, that is: Which steps x86 follows to handle any interrupt ?
Mehmet Ali
  • 91
  • 1
  • 2
9
votes
1 answer

Why can't MOV have both operands as memory locations?

I read that MOV instruction cannot have memory locations for both its operands. Like : MOV [0012H], [0016H] is not allowed. Why so? And can other instructions have memory locations for both its operands?
batman
  • 5,022
  • 11
  • 52
  • 82
9
votes
1 answer

Operand size prefix in 16-bit mode

I'm trying to understand GAS's behavior of .code16. From the manual, it seems in 16-bit section, for 32-bit operands or instructions, a 66H operand override prefix will be produced for the instruction encoding. Does that mean .code16 movw %eax,…
Oxdeadbeef
  • 1,033
  • 2
  • 11
  • 26
9
votes
2 answers

What would happen if the CS segment register is changed? (And how would you do so?)

I read this article: http://static.patater.com/gbaguy/day3pc.htm It includes the sentence DON'T EVER CHANGE CS!! But what exactly would happen if you did modify the CS segment register? Why is it so dangerous?
SmRndGuy
  • 1,719
  • 5
  • 30
  • 49
9
votes
1 answer

PC boot: dl register and drive number

I read somewhere in the internet that, before jumping to 0x7c00, the BIOS loads into %dl the "drive number" of the booted device. But what is this "drive number"? Each device attached to the computer is assigned a number by the BIOS? If so, how can…
KevinRGT
  • 389
  • 2
  • 5
  • 14
8
votes
1 answer

Registering Interrupt in 16 bit x86 Assembly

I am writing my own OS in 16 bit x86 Assembly, and I'm trying to register my own interrupt, something like INT 21H in MS-DOS. I couldn't find anything on the web. I'm using NASM as the assembler.
Xyz
  • 212
  • 2
  • 9