Post

Surviving the 8086 Assembly Course

The blog series which contains all the core components to know so that you can pass your 8086 assembly lab course

Surviving the 8086 Assembly Course

Pretalk

If you’re studying in Bangladesh or India, there’s a good chance that your assembly language practical course uses 8086 Assembly with the EMU8086 software. This approach is quite common in academic settings. However, it’s also true that assembly language isn’t widely used in most modern development workflows, so many instructors may have limited hands-on experience with it beyond their own education. As a result, some of the teaching may focus more on theory than practical, real-world applications.

But you have to pass this course with and you cannot bullshit your way through considering the examiner’s theoratical knowledge will kick off the bullshit sensor in their brain when you try to do so. So we will focus on only the necessary things we need to know to make sure we don’t fail and we don’t trip their bullshit sensor as well.

Knowledge needed

If you are using EMU8086 in the exam you can get pass by using the built in snippets but most teachers will just cut some portions of the program and make you rewrite that on the spot, in that case you need to know some theory and coding tricks before you even try to attempt something

  1. Registers and memory of the 8086 microprocessor
  2. Sections of assembly code
  3. Which instructions with which memory can work and which combinations of source and destinations are legal
  4. The AH value that does special functions that you may need to use
  5. The process of coding it in any low level language like C
  6. Commenting the code frequently to make the code more readable and use the C program as your coding reference

8086 Registers

8086 memory shown in emu8086 software

8086 microprocessor is a 16bit microprocessor and there are three kinds of registers in 8086 microprocessors. they are

  1. General Purpose Registers
16-bitHigh byte (8-bit)Low byte (8-bit)Common Use
AXAHALAccumulator (for arithmetic)
BXBLBHBase (used in addressing)
CXCHCLCounter (used in loops, shifts)
DXDHDLData (used in I/O, multiplication)
  1. Index Pointer Registers
RegisterPurpose
SPStack Pointer (points to top of the stack)
BPBase Pointer (used to access parameters in stack frames)
SISource Index (used in string/memory operations)
DIDestination Index (used in string/memory operations)
  1. Segment Registers
RegisterPurpose
CSCode Segment (where instructions are fetched from)
DSData Segment (default for variables)
SSStack Segment (used with the stack)
ESExtra Segment (used for string operations)
  1. Flag Registers
FlagDescription
CFCarry Flag
ZFZero Flag
SFSign Flag
OFOverflow Flag
PFParity Flag
AFAuxiliary Carry (used in BCD)
DFDirection Flag (used in string ops)
IFInterrupt Enable Flag

Code Sections

In 8086 Assembly, the program is typically divided into several segments, each with a specific purpose.

Here’s a breakdown of the most commonly used segments:

.model

The .model directive specifies the memory model of the program — it tells the assembler how code and data are organized.

Common Memory Models:

Memory ModelDescription
`.model tiny`Code + data fit in 1 segment (COM programs)
`.model small`Code and data each have one segment
`.model medium`Code can span multiple segments, data in one
`.model large`Code and data both can be in multiple segments

For beginners, .model small is the most commonly used.

1
.model small

.data

The .data segment is where you declare initialized variables (data that has a known starting value).

Examples:

1
2
3
.data
msg     db  'Hello, World$', 0
number  dw  1234h

.stack

The .stack segment reserves memory for the stack, which is used for function calls, pushing/popping values, etc.

You define how much memory (in bytes) you want to allocate for it:

1
.stack 100h   ; reserve 256 bytes for the stack

Stack operations use SP (Stack Pointer) and SS (Stack Segment) registers.

.code

This is where you write your actual instructions (the program logic). It corresponds to the Code Segment (CS) in memory.

Typical Structure:

1
2
3
4
5
6
7
8
9
10
.code
main proc
    mov ax, @data
    mov ds, ax

    ; Program codes 

    mov ah, 4ch
    int 21h    ; exit to DOS
main endp

Memory Permutations

In 8086 (and most x86 architectures), you cannot use two memory operands in a single instruction. For example:

Valid example:

1
2
MOV AX, [BX]     ; move from memory at address in BX to AX
MOV [SI], AX     ; move from AX into memory at address in SI

Invalid (two memory operands) example:

1
MOV [BX], [SI]   ; illegal: both source and destination are memory

Why this happens:

In x86 architecture, the CPU’s instruction set encoding doesn’t support directly transferring data from one memory location to another in a single instruction. It requires the CPU to work with a register as an intermediary.

So you must break it into two steps:

1
2
MOV AX, [SI]     ; load from source memory
MOV [BX], AX     ; store into destination memory

General Rule of Thumb:

Only one memory operand is allowed in most x86 instructions (MOV, ADD, SUB, etc.) — the other operand must be a register or an immediate value.

Allowed Combinations in MOV:

  1. Register ↔ Register
  2. Register ↔ Memory
  3. Register ↔ Immediate

not allwed in MOV

  1. Memory ←→ Memory

One trick is to use register to register for all instructions. as that is allowd in all of the instructions

AH functions

DOS Interrupt 21h Functions are the one used in AH and that value does some particular task. The task corresponding to the value is

AH ValueFunction NamePurpose
01hInput character (with echo)Waits for keypress and echoes it on screen
02hDisplay characterPrints the character in DL
06hDirect console I/OInput/output without echo
07hInput character (no echo)Like 01h but without echoing
08hInput character (no echo, no wait)Reads a key only if one is pressed
09hDisplay stringDisplays a $-terminated string from DX
0AhBuffered string inputReads string input into a buffer (first byte = max length)
0EhSelect default driveDL = drive number (0=A, 1=B, etc.)
25hSet interrupt vectorChange ISR for a given interrupt
2AhGet system dateReturns date in CX, DX, AL
2ChGet system timeReturns time in CX, DX
31hTerminate and stay residentKeeps part of the program in memory (TSR)
4ChTerminate programEnd program with optional return code in AL

Conclusion

This are all the theories that are absolutely necessary to make sure you can at least get past the minimum requirement to at least read the template codes in the software and get past the coding task.

This post is licensed under CC BY 4.0 by the author.