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
1
vote
3 answers

Writing a string to a file gives output with weird characters in assembly

I am trying to save my string to a file in assembly but it gives me this weird output with "ver 2.40 (all kinds of special characters)" This is what I do: mov ah,09 mov dx,200 int 21 int 20 e 200 "Test$" n test.com r cx :0009 w q It saves it…
Sinan Samet
  • 6,432
  • 12
  • 50
  • 93
1
vote
1 answer

Calling a procedure by pointer from variable in Intel 8086 Assembly

Let's say I have a variable with procedure address: func_pointer dw offset my_function my_function proc near my_function endp How can I call it from the variable? I have tried call dword ptr[func_pointer + 1] but it does not seem to work.
1
vote
2 answers

Pointers and Indexes in Intel 8086 Assembly

I have a pointer to an array, DI. Is it possible to go to the value pointed to by both DI and another pointer? e.g: mov bl,1 mov bh,10 inc [di+bl] inc [di+bh] And, on a related note, is there a single line opcode to swap the values of…
Raven Dreamer
  • 6,940
  • 13
  • 64
  • 101
1
vote
1 answer

Simplify assembly program

I currently have this code: .model small .stack 100h .data .code CLRSCR: mov ax,0003h int 10h ROWCOLINIT: mov dh,0 mov dl,0 MYLOOP: mov ax,dx mov ah,0 mov bl,2 div bl …
sky_flakes
  • 21
  • 1
1
vote
1 answer

emu8086 : ARR do not contain any value

I was trying to implement QUICK SORT in assembly language .When I run the code in emulator , the array 'ARR' contains only zeros, no values are loaded. I don't know what I do wrong . (ARR is defined at the end of the code.) CODE SEGMENT ASSUME…
Anklon
  • 618
  • 2
  • 8
  • 21
1
vote
1 answer

x86 ASM - Read line by line

Okay, all I want to do is just read line by line from text and then output it. Things I do: Read single char, add to string Search for LF Output string Do all over again until EOF Problems: No idea how to count cx for 40h interrupt while It's…
RendoJack
  • 366
  • 1
  • 5
  • 17
1
vote
2 answers

comparing numeric ASCII codes instead of character constants? And using fewer compares to find brackets?

cmp s1,'(' je truth cmp s1,')' je truth cmp s1,'[' je truth cmp s1,']' je truth cmp s1,'{' je truth cmp s1,'}' je truth jne false I want to ask how can I use ASCII code to…
Assault
  • 23
  • 3
1
vote
1 answer

CMP and jmp variations in assembly

cmp al,'0' je true cmp al,'1' je true cmp al,'2' je true cmp al,'3' je true cmp al,'4' je true cmp al,'5' je true cmp al,'6' je true cmp al,'7' je true cmp al,'8' je true cmp al,'9' je true jne error I`m interested how to…
Arashigor
  • 171
  • 3
  • 12
1
vote
1 answer

How can I convert binary to decimal in 8086 assembly (NASM)?

Let me say first of all I barely know what I'm doing, I'm aware. Basically, the idea is to convert from decimal to binary, and then back to decimal (pointless, I know). I've successfully converted the decimal to binary, but now I need to convert it…
Brandon Copeland
  • 125
  • 1
  • 2
  • 9
1
vote
0 answers

How can I move an 8-bit number to address 00FEh?

I'm studying 8086 assembly and I have this question: Move the content of BL (an 8-bit number) to the address 00FEh. Use base addressing with a displacement offset. I made this: MOV 00FEh,BL but TASM gives an error. esempio1.asm(16) illegal…
Thorny84
  • 325
  • 3
  • 22
1
vote
3 answers

Multiply two 16 bit numbers and store 32 bit answer in dx:ax without mul instruction in assembly 8086

I am trying to multiply two 16 bits numbers using the shift and add methods in assembly language and store the hi part in the dx register and the low part in the ax register. The multiplicand and multiplier are passed on the stack For some of my…
mukhtar23
  • 21
  • 1
  • 4
1
vote
1 answer

Objdump of .code16 and .code32 x86 assembly

I have this assembly code (on Linux): .globl _start _start: cli xorw %ax,%ax # Set %ax to zero movw %ax,%ds movw %ax,%es movw %ax,%ss I first add…
Kamalakshi
  • 6,918
  • 3
  • 17
  • 21
1
vote
1 answer

Physical address calculation assembly IAPX8088

Given that: CS=0x5645, DS=0x1000, ES=0x6783, SS=0x0FFF, BX=0x4567, SI=0x1000, DI=0x2000, BP=0x4500 Write the physical address of the memory locations read or written by the following instructions if ax=0. mov ax,[si] mov ax,[bp] mov…
Saqib Khan
  • 53
  • 2
  • 7
1
vote
1 answer

8086 Assembly interrupts for reading/writing binary to/from files?

I need to read in about 1KB or so of data at a time, manipulate it, and write it to another file. I need to do this for at least 100 MB. I have never done any file IO in assembly before. What interrupts do I need to call and what needs to be in what…
Corey Ogburn
  • 24,072
  • 31
  • 113
  • 188
1
vote
2 answers

Using registers and variables in 8086 asm programming

I am starting to get to grips with asm programming but I feel I am missing something regarding the use of registers to store variables. The issue that I have is that some instructions will modify other registers for internal reasons. In some cases I…
Garry Taylor
  • 940
  • 8
  • 19