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
5
votes
1 answer

Upper bits of EBX are zeroed out when single-stepping in CodeView

I have the following simple program written in MASM for an i386 processor: TITLE BLA .MODEL SMALL .386 .STACK .DATA .CODE MAIN PROC FAR .STARTUP MOV EBX,0FFFFFFFFH; (1) …
jupiter_jazz
  • 333
  • 2
  • 8
5
votes
1 answer

Calling procedures from another file

I have an .ASM file in which I want to call procedures from another .ASM or .INC file. I have tried writing the following into my main.asm file: INCLUDE file_op.inc However when I try to run it, it just says: 'the emulator is halted.' It does…
Michael Kročka
  • 617
  • 7
  • 22
5
votes
1 answer

Setting segment registers after ORG instruction

I am currently following a tutorial on OS development, which includes a discussion on bootloaders. My bootloader is currently in 16-bit real mode, therefore, I am able to use the BIOS interrupts provided (e.g. VGA video interrupts, etc.). The BIOS…
Code Doggo
  • 2,146
  • 6
  • 33
  • 58
5
votes
2 answers

When Will the Code Under DATA SEGMENT execute in this code?

I am a beginner of Assembly Programming... I surfed a lot in google. There is a lot of information, but I still do not understand the following code. I would be grateful if someone could explain MOV AX,DATA I also don't understand when the code that…
Muthu Ganapathy Nathan
  • 3,199
  • 16
  • 47
  • 77
5
votes
1 answer

Why does CX work in '[ ]' in 16 Bit Assembly when it is not a base or index register?

When using MASM 6.15 under DOSBox whenever I try to do: mov al, [cx] or mov al, [cx + bx] or mov al, [cx + 4] I am getting the error: 'Only Base or Index Registers are allowed' But then again, let's say I have an array var1. If I do: .model…
Parker Queen
  • 619
  • 2
  • 12
  • 27
5
votes
0 answers

modern c++ for 16-bit binaries?

It's a silly question, but... I have recently played with djgpp and was surprised one can compile/link modern c++17 code into 32-bit dos binaries. Mingw covers win32 and win64. But there's a gaping hole as regards win16. Are there any c++17…
user1095108
  • 14,119
  • 9
  • 58
  • 116
5
votes
1 answer

Why do x86 jump/call instructions use relative displacements instead of absolute destinations?

I am learning 8086 and there is one particular question which is bothering me and I have not been able to find any satisfactory answer yet. I understand that CPU executes the code sequentially and if want to change the code flow we would like the IP…
Albert
  • 415
  • 5
  • 15
5
votes
1 answer

Displaying numbers with DOS

I was tasked to write a program that displays the linear address of my program's PSP. I wrote the following: ORG 256 mov dx,Msg mov ah,09h ;DOS.WriteStringToStandardOutput int 21h …
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
5
votes
1 answer

how to seed a random number generator in assembly?

I'm trying to create a complete random number in assembly but it's every time I start the program it gives me the same numbers, in the same order. If the numbers are 12, 132, 4113 or something, it'll repeat them every time I start the code. The…
S. josh
  • 79
  • 7
5
votes
1 answer

Explain how the AF flag works in an x86 instructions?

I have a little 8086 emulator and I've had a long standing bug for like 2 years now that AF does not behave properly inside of sub and add instructions. My current way of computing its value is this for 8 bit numbers and subtraction: uint8_t…
Earlz
  • 62,085
  • 98
  • 303
  • 499
5
votes
1 answer

What is the purpose of the reserved/undefined bit in the flag register?

In the flag register of Z80, 8080, 8085, and 8086 processors, what is the purpose of bits 1, 3, 5, which are documented as "reserved" or "undefined"?
Joseph
  • 55
  • 7
5
votes
1 answer

Is there a way to use math expressions in gnu assembly constants?

What is the correct gnu assembly syntax for doing the following: .section .data2 .asciz "******* Output Data ********" total_sectors_written: .word 0x0 max_buffer_sectors: .word ((0x9fc00 - $data_buffer) / 512) # <=== need help here .align…
Zack
  • 6,232
  • 8
  • 38
  • 68
5
votes
1 answer

What would cause a disk read error in Int 13h?

I've been writing a test program in NASM for a function that uses int 13h to read sectors off the booted disk except every time I run the assembled program with sudo qemu-system-i386 load_disk.bin it gives me this output: disk read error! disk…
Hopeful
  • 55
  • 7
5
votes
2 answers

What are 8086 ESC instruction opcodes

Mostly of a historical interest and if I were to implement 8086 compatibility for assembler, what operands are considered valid for ESC instruction? ESC opcode, source From 8086 Programmer's manual I know, that opcode is an immediate in range 0 to…
Alexander Zhak
  • 9,140
  • 4
  • 46
  • 72
5
votes
2 answers

Insert a new line assembly 8086

I'm learning assembly language and I have a doubt. I'm programming a simple "hello world" with this code: .model small .stack .data message db 'Hello world! $' .code start: mov dx,@data mov ds.dx lea dx,message move ah,09h …