COSC 323
PROGRAMMING IN
INTEL 8086
ASSEMBLY
Intel 8086 CPU Registers Cont’d
• The Intel 8086 CPU has 14 internal registers, each one of 16 bits (2bytes).
• The full name of the fourteen registers are:
AX Accumulator
BX Base register
CX Counting register
DX Data register
DS Data segment register
ES Extra segment register
SS Stack segment register
CS Code segment register
BP Base pointers register
SI Source index register
DI Destination index register
SP Stack pointer register
IP Next instruction pointer register
Flags register in the ALU
Intel 8086 CPU Registers Cont’d
Intel 4 General Purpose Registers and their functions
Register Names Special purpose or Functions
AX (AH & AL) Accumulator Reg. Arithmetic operations (ADD, SUB, DIV & MUL)
BX (BH & BL) Base address Reg. Index register for MOVE, Memory, DIV and
MUL operations
CX (CH & CL) Count register For ASCII string operations
DX (DH & DL) Data register Port address for IN and OUT operations
Knowing the syntax in Intel 8086 assembly language and memory Access
Some of the following are important syntax to note when writing Intel assembly language:
The order of the operands is destination, source
Semicolons (;) begin a comment. Anything that follows semi-colon (;) is ignored by the assembler.
The suffix ’H’ is used to indicate a hexadecimal constant, if the constant begins with a letter it must be prefixed
with a zero to distinguish it from a label
The suffix ’B’ indicates a binary constant or D is Decimal constant
The suffix ’Q’ or ‘O’ indicates a Octal constant
Square brackets indicate indirect addressing or direct addressing to memory (with a constant)
These four registers can be used to access memory: BX, SI, DI, BP. Combining them inside [ ] symbols
The size of the transfer (byte or word) is determined by the size of the register
The comma (,) is used to separate the two operands
ASCII characters are always in quote (e.g. letter A should be ‘A’).
Instructions or mnemonic codes can be written either in uppercase letter or lowercase letter. MOV mov Mov mOv
Common Intel 8086 Instructions
MOV Instruction
The MOV instruction takes two operands, representing the destination where data is to be placed and the source of that
data.
General Form of MOV Instruction in Intel 8086 is:
MOV destination, source e.g. MOV AX, 8
• Where Destination must be either a register or memory location and
• Source may be a constant, another register or a memory location.
In 8086 assembly language, the source and destination cannot both be memory locations in the same instruction.
MOV copies a number in a register or in a memory location (a variable) i.e. it assigns a value to a register or variable.
The following illustrates the MOV instruction.
Copies the second operand (source) to the first operand (destination).
The source operand can be an immediate value, general-purpose register or memory location.
The destination register can be a general-purpose register, or memory location.
Both operands must be the same size, OR the source operand must smaller than the destination which can be a byte or
a word.
MOV Instruction Cont’d
These types of operands are supported by MOV Instruction
MOV REG, memory
MOV memory, REG
MOV REG, REG
MOV memory, immediate
MOV REG, immediate
REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.
memory: [BX], [BX+SI+7], variable, etc...
Mov bx, 6
Mov ax, [bx]
immediate: 5, -24, 3Fh, 10001101b, etc...
MOV Instruction Cont’d
For segment registers only these types of MOV are supported:
MOV SREG, memory
MOV memory, SREG
MOV REG, SREG
MOV SREG, REG
SREG: DS, ES, SS, and only as second operand: CS.
REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.
memory: [BX], [BX+SI+7], variable, etc...
MOV Instruction Cont’d
MOV instruction Examples with the comment statement after (;).
mov bx, 4 ; copy number 4 into register bx
mov ax, bx ; copy contents of bx into register ax
mov cx, ax ; copy contents of ax into register cx
Note that a missing comma is a common syntax error.
The MOV instruction cannot be used to set the value of the CS and IP registers.
MOV Instruction Cont’d
Example using ASCII code conversion:
Store the ASCII code for the letter A in register bx.
Solution: A has ASCII code 65D (01000001B, 41H). See appendix A in the text book
Therefore, the following mov instruction can be used to carry out this task as:
mov bx, 65d
This could also be written as:
mov bx, 41h
or mov bx, 01000001b
or mov bx, ‘A’
65D
bx 0000 0000 0100 0001 mov bx, 65D
bit bit
15 0
The effect of executing mov bx, 65D as a 16-bit number
MOV Instruction Cont’d
Data Transfer using MOV instruction also known as register addressing
The MOV instruction is used to transfer 8 and 16-bit data to and from registers.
For example:
If COUNT is the label of a memory location the following are possible assembly-language instructions:
MOV AX, BX ; register: move contents of BX to AX
MOV AX, COUNT ; direct: move contents of the address labeled COUNT to AX
(where COUNT is a variable, e.g. COUNT = 10)
MOV CX, 0F0H ; immediate: load CX with the value 240
MOV BX, [0F0H] ; memory indirect: load BX with the value at address 240
MOV [BX], AL ; register indirect: move contents of AL to memory location in
BX
Using Arithmetic & Logic Instructions
First Group: ADD, SUB, CMP, AND, TEST, OR, XOR.
These types of operands are supported thus:
REG, Memory
Memory, REG
REG, REG
Memory, Immediate
REG, Immediate
REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.
Second group: MUL, IMUL, DIV, IDIV.
This types of operands are supported thus:
REG
Memory
REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.
Using Arithmetic & Logic Instructions
Third group: INC, DEC, NOT, NEG
These types of operand are supported:
REG
Memory
REG: AX, BX, CX, DX, AH, AL, BL, BH, CH, CL, DH, DL, DI, SI, BP, SP.
NOT - Reverse each bit of operand.
NEG - Make operand negative (two's complement). Actually it reverses each
bit of operand and then adds 1 to it. For example. 5 will become -5 and 2 will
become -2.
Using Arithmetic & Logic Instructions
Example of using arithmetic and logic instructions
ADD BX, 4 ; increment BX by 4
SUB AL, 1 ; subtract 1 from AL
INC BX ; increment BX by one value
CMP AX, MAX ; compare (subtract and set flags but without storing result)
AND AL, 0FH ;mask in LS 4 bits of AL
SHR AX, 2 ; divide AX by 4 (i.e. 22); if AX = 8 ie. Answer is 2
SHL AX, 3 ; Multiply AX by 8 (i.e. 23); if AX = 8 , answer is 64
OR CX, 8000H ; set MS bit of CX
XOR AX, AX ; clear AX
add, inc, dec, mul, div and sub instructions
• The 8086 provides a variety of arithmetic instructions.
• To carry out arithmetic such as addition or subtraction, etc, appropriate instruction must be
used.
Example:
mov ax, 5 ; load 5 into ax
add ax, 3 ; add 3 to the contents of ax, ax now contains 8
inc ax ; add 1 to ax, ax now contains 9 (Only Operand)
dec ax ; subtract 1 from ax, ax now contains 8 (only operand)
sub ax, 6 ; subtract 6 from ax, ax now contains 2
Note that the inc and dec instructions take only one operand. The mul (or imul for sign value)
and div (or idiv for sign value) also take only one operand.
SOME COMMON FUNCTIONS (Emu8086 Macro functions)
To make programming easier there are some common functions that can be included in the program.
To use any of the functions in emu8086.inc the following line must be included in the beginning of
the source file:
include 'emu8086.inc'
PUTC char - macro with 1 parameter; prints out an ASCII char at current cursor position.
GOTOXY col, row - macro with 2 parameters; sets cursor position.
PRINT string - macro with 1 parameter; prints out a string.
PRINTN string - macro with 1 parameter; prints out a string. The same as PRINT but
automatically adds "carriage return" at the end of the string.
CURSOROFF - turns off the text cursor.
CURSORON - turns on the text cursor.
SOME COMMON FUNCTIONS (Emu8086 Macro functions)
include emu8086.inc
ORG 100h
PRINT 'Hello World!'
GOTOXY 5, 5
PUTC 65 ; 65 - is an ASCII code for 'A'
PUTC 'B'
RET ; return to operating system.
END ; directive to stop the compiler.
When compiler process the source code it searches the emu8086.inc file for declarations of
the macros and replaces the macro names with real code.
Emu8086 procedure functions
Emu8086.inc also defines the following procedures:
PRINT_STRING - procedure to print a null terminated string at current cursor position,
- To use it declare: DEFINE_PRINT_STRING before END directive.
SI
PTHIS - procedure to print a null terminated string at current cursor position (just as
PRINT_STRING),
For example:
CALL PTHIS
db 'Hello World!', 0
- To use it declare: DEFINE_PTHIS before END directive.
Emu8086 procedure functions Cont’d
GET_STRING - procedure to get a null terminated string from a user DI
- To use it declare: DEFINE_GET_STRING before END directive.
CLEAR_SCREEN - procedure to clear the screen, (done by scrolling entire screen window
- To use it declare: DEFINE_CLEAR_SCREEN before END directive.
SCAN_NUM - procedure that gets the multi-digit SIGNED number from the keyboard, and
stores the result in CX register.
- To use it declare: DEFINE_SCAN_NUM before END directive.
PRINT_NUM - procedure that prints a signed number in AX register. To use it declare:
DEFINE_PRINT_NUM and DEFINE_PRINT_NUM_UNS before END directive.
PRINT_NUM_UNS - procedure that prints out an unsigned number in AX register.
- To use it declare: DEFINE_PRINT_NUM_UNS before END directive.
Include 'emu8086.inc'
ORG 100h
LEA SI, msg1 ; ask for the number (LEA is Load Effective Address)
CALL print_string ;
CALL scan_num ; get number in CX.
MOV AX, CX ; copy the number to AX.
CALL pthis
DB 13, 10, 'You have entered: ', 0
CALL print_num ; print number in AX.
RET ; return to operating system.
msg1 DB 'Enter the number: ', 0
DEFINE_SCAN_NUM
DEFINE_PRINT_STRING
DEFINE_PRINT_NUM
DEFINE_PRINT_NUM_UNS ; required for PRINT_NUM.
DEFINE_PTHIS
END ; directive to stop the compiler.
How to define and use Variables in Intel 8086
Variable is a memory location.
For a programmer it is much easier to have some value kept in a variable named "var1“
The Emu 8086 compiler supports two types of variables: BYTE and WORD
E. g.
Syntax for a variable declaration:
name DB value
name DW value
DB - stays for Define Byte.
DW - stays for Define Word.
name - can be any letter or digit combination, though it should start with a letter
value - can be any numeric value in any supported numbering system (hexadecimal, binary, or decimal), or "?"
symbol for variables that are not initialized
Intel Variable Cont’d
Programming Example of how to use Intel Variable
ORG 100h
MOV AL, var1
MOV BX, var2
RET ; stops the program.
var1 DB 7
var2 DW 1234h
end
NOTE that:
DW can be used instead of DB if it's required to keep values larger than 255, or smaller than -128.
Intel Variable Cont’d
Getting the Address of a Variable
There is LEA (Load Effective Address) instruction and alternative OFFSET operator.
Both OFFSET and LEA can be used to get the offset address of the variable.
Note that:
LEA is more powerful because it also allows the programmer to get the address of indexed variables.
These lines do the same thing:
LEA BX, VAR1
MOV BX, OFFSET VAR1
Both examples have the same functionality.
Please Note that only these registers can be used inside square brackets (as memory pointers): BX, SI, DI, BP.
Intel Variable Cont’d
Example 1: Using LEA Example 2: Using OFFSET
; demonstrate get_string and print_string
;----------------------------------------
include 'emu8086.inc'
ORG 100h
LEA SI, msg1 ; set up pointer (SI) to msg
; to ask for the number
CALL print_string ; print message that SI points to
LEA DI, buffer ; set up pointer (DI) to input buffer
MOV DX, bufSize ; set size of buffer
CALL get_string ; get name & put in buffer
LEA SI, newln ; point at CR/LF / Hello message
CALL print_string ; print message that SI points to
RET ; return to operating system.
; data
msg1 DB "Enter your name: ", 0
newln DB 13, 10
DB "Hello, "
buffer DB 20 DUP (0) ; input buffer for get_string
bufSize = $-buffer ; calculates size of buffer
DEFINE_GET_STRING
DEFINE_PRINT_STRING
END ; directive to stop the compiler.
; demonstrate scan_num, print_num, pthis
;----------------------------------------
include 'emu8086.inc'
ORG 100h
LEA SI, msg1 ; ask for the number
CALL print_string ;
CALL scan_num ; get number in CX.
MOV AX, CX ; copy the number to AX.
; print the following string:
CALL pthis
DB 13, 10, 'You have entered: ', 0
CALL print_num ; print number in AX.
RET ; return to operating system.
; data
msg1 DB 'Enter the number: ', 0
; macros to define procs
DEFINE_SCAN_NUM
DEFINE_PRINT_STRING
DEFINE_PRINT_NUM
DEFINE_PRINT_NUM_UNS ; required for print_num.
DEFINE_PTHIS
END ; directive to stop the compiler.
Thanks