Category:8086 Assembly: Difference between revisions

From Rosetta Code
Content added Content deleted
(categorize, etc.)
No edit summary
Line 1: Line 1:
{{Stub}}{{language}}{{assembler language}}[[Category:Assembly]]8086 Assembly is the assembly language used by the Intel 8086 processor. This processor was used for the first time in the IBM PC, and in its various clones. The 8086 gave birth, starting with the 80186 processor, to the X86 family, that nowadays is the most used processor family in desktop computers. All the 32 and 64 bit processors from this family are able to operate in a 8086 compatibility mode, for backward compatibility with legacy software and running very low-level code (like the BIOS). For the evolution of this assembly implementation to 32 bits, see [[X86 assembly]].
{{Stub}}{{language}}{{assembler language}}[[Category:Assembly]]8086 Assembly is the assembly language used by the Intel 8086 processor. This processor was used for the first time in the IBM PC, and in its various clones. The 8086 gave birth, starting with the 80186 processor, to the X86 family, that nowadays is the most used processor family in desktop computers. All the 32 and 64 bit processors from this family are able to operate in a 8086 compatibility mode, for backward compatibility with legacy software and running very low-level code (like the BIOS). For the evolution of this assembly implementation to 32 bits, see [[X86 assembly]].

==Architecture Overview==
===Segmented Memory===
The 8086 uses a segmented memory model, similar to the Super Nintendo Entertainment System. Unlike banked memory models used in the [[Commodore 64]] and late NES games, segment addresses are held in <i>segment registers</i>. These segment registers are 16 bit and get left-shifted by 4 and added to the pointer register of interest to determine the memory address to look up. The 8086 has four in total, but only the Data Segment and Extra Segment can be used by the programmer. (The other two are reserved for the stack pointer and instruction pointer.) On the 8086, you can only load segment registers with the value in a data register, or with the <code>POP</code> command. So first you must load a segment into a data register, THEN into a segment register.

===Data Registers===
There are four data registers: <code>AX</code>, <code>BX</code>, <code>CX</code>, and <code>DX</code>. While most commands can use any of them, some only work with particular data registers. System calls in particular are very specific about which registers can be used for what. On [[MS-DOS]], the AX register is used for selecting the desired interrupt to use with the <code>INT</code> command.

Each data register is 16-bit, but has two eight bit halves ending in H or L, e.g. <code>AH, AL</code>. Instructions can be executed using the whole register or just half of it.
<lang asm>mov ax, 1000h ;move 1000h into AX, or equivalently, move 10h into AH and 00h into AL.</lang>
Moving a value smaller than 16 bits into ?X is the same as moving it into ?L. and moving 0 into ?H. (? represents the data register of your choice. They are all the same in this regard.)

<lang asm>mov ax,0030h
mov al, 30h
mov ah, 0h</lang>

Generally speaking, the 8086's registers serve the following purposes:
* AX is the "Accumulator" and is used for advanced mathematics routines, as well as the source/destination for the <code>STOSW</code> and <code>LODSW</code> commands when loading/storing bytes from consecutive regions of memory.
* BX can be used as a variable offset on the Source Index/Destination Index registers (more on those later).
* CX is used as a loop counter. The <code>JCXZ</code> command jumps to the specified address, but only if CX = 0.
* DX can be used to specify a shift amount when bit shifting. Later versions of the x86 family allow this to be an arbitrary immediate value, but on the original 8086 you can only specify 1 or DX.

===Other Registers===
When writing to or reading from consecutive sections of memory, it is helpful to apply an offset from a base value. The Base Pointer register <code>BP</code>, Source Index <code>SI</code>, and Destination Index <code>DI</code> can point to various regions of memory. Many commands that work with these registers can auto-increment or decrement them after each load or store. In addition, they can be optionally offset by a constant, or the value stored in <code>BX</code>.


===The Stack===
As with [[Z80 Assembly]], you can't push 8-bit registers onto the stack. For data registers, you have to push/pop both halves.
<lang asm>;This is valid code.
push ax
push bx

pop bx
pop ax</lang>

<lang asm>;This is NOT valid code.
push ah
push al
push bh
push bl


pop bl
pop bh
pop al
pop ah</lang>

As with all processors that use a stack, if you push one or more registers and want to restore the backed-up values correctly, you must pop them in the reverse order. You can pop them out of order on purpose to swap registers around. In fact, this is a quick way to move the segment from <code>DS</code> into <code>ES</code>, or vice-versa:
<lang asm>push DS
pop ES ;you can't do "mov es, ds" but you can do this!

===Arithmetic===
The 8086 has a lot of advanced mathematics commands. Like the 68000 it can multiply and divide. Although the 8086 doesn't work with 32 bit numbers in a single register, it has many more options for Binary Coded Decimal values, including commands for both "packed" (two digits per byte) and "unpacked" (one digit per byte.) By contrast, [[68000 Assembly]] only has commands for the "packed" format.


[[category: x86 Assembly]]
[[category: x86 Assembly]]

Revision as of 17:25, 17 September 2021

This page is a stub. It needs more information! You can help Rosetta Code by filling it in!
Language
8086 Assembly
This programming language may be used to instruct a computer to perform a task.
See Also:


Listed below are all of the tasks on Rosetta Code which have been solved using 8086 Assembly.

8086 Assembly is the assembly language used by the Intel 8086 processor. This processor was used for the first time in the IBM PC, and in its various clones. The 8086 gave birth, starting with the 80186 processor, to the X86 family, that nowadays is the most used processor family in desktop computers. All the 32 and 64 bit processors from this family are able to operate in a 8086 compatibility mode, for backward compatibility with legacy software and running very low-level code (like the BIOS). For the evolution of this assembly implementation to 32 bits, see X86 assembly.

Architecture Overview

Segmented Memory

The 8086 uses a segmented memory model, similar to the Super Nintendo Entertainment System. Unlike banked memory models used in the Commodore 64 and late NES games, segment addresses are held in segment registers. These segment registers are 16 bit and get left-shifted by 4 and added to the pointer register of interest to determine the memory address to look up. The 8086 has four in total, but only the Data Segment and Extra Segment can be used by the programmer. (The other two are reserved for the stack pointer and instruction pointer.) On the 8086, you can only load segment registers with the value in a data register, or with the POP command. So first you must load a segment into a data register, THEN into a segment register.

Data Registers

There are four data registers: AX, BX, CX, and DX. While most commands can use any of them, some only work with particular data registers. System calls in particular are very specific about which registers can be used for what. On MS-DOS, the AX register is used for selecting the desired interrupt to use with the INT command.

Each data register is 16-bit, but has two eight bit halves ending in H or L, e.g. AH, AL. Instructions can be executed using the whole register or just half of it. <lang asm>mov ax, 1000h ;move 1000h into AX, or equivalently, move 10h into AH and 00h into AL.</lang> Moving a value smaller than 16 bits into ?X is the same as moving it into ?L. and moving 0 into ?H. (? represents the data register of your choice. They are all the same in this regard.)

<lang asm>mov ax,0030h mov al, 30h mov ah, 0h</lang>

Generally speaking, the 8086's registers serve the following purposes:

  • AX is the "Accumulator" and is used for advanced mathematics routines, as well as the source/destination for the STOSW and LODSW commands when loading/storing bytes from consecutive regions of memory.
  • BX can be used as a variable offset on the Source Index/Destination Index registers (more on those later).
  • CX is used as a loop counter. The JCXZ command jumps to the specified address, but only if CX = 0.
  • DX can be used to specify a shift amount when bit shifting. Later versions of the x86 family allow this to be an arbitrary immediate value, but on the original 8086 you can only specify 1 or DX.

Other Registers

When writing to or reading from consecutive sections of memory, it is helpful to apply an offset from a base value. The Base Pointer register BP, Source Index SI, and Destination Index DI can point to various regions of memory. Many commands that work with these registers can auto-increment or decrement them after each load or store. In addition, they can be optionally offset by a constant, or the value stored in BX.


The Stack

As with Z80 Assembly, you can't push 8-bit registers onto the stack. For data registers, you have to push/pop both halves. <lang asm>;This is valid code. push ax push bx

pop bx pop ax</lang>

<lang asm>;This is NOT valid code. push ah push al push bh push bl


pop bl pop bh pop al pop ah</lang>

As with all processors that use a stack, if you push one or more registers and want to restore the backed-up values correctly, you must pop them in the reverse order. You can pop them out of order on purpose to swap registers around. In fact, this is a quick way to move the segment from DS into ES, or vice-versa: <lang asm>push DS pop ES ;you can't do "mov es, ds" but you can do this!

Arithmetic

The 8086 has a lot of advanced mathematics commands. Like the 68000 it can multiply and divide. Although the 8086 doesn't work with 32 bit numbers in a single register, it has many more options for Binary Coded Decimal values, including commands for both "packed" (two digits per byte) and "unpacked" (one digit per byte.) By contrast, 68000 Assembly only has commands for the "packed" format.

Subcategories

This category has the following 3 subcategories, out of 3 total.

Pages in category "8086 Assembly"

The following 123 pages are in this category, out of 123 total.