0% found this document useful (0 votes)
29 views53 pages

Final Microprocessor and Assembly Language Programming Lab

Uploaded by

Dawit Birhanu
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
0% found this document useful (0 votes)
29 views53 pages

Final Microprocessor and Assembly Language Programming Lab

Uploaded by

Dawit Birhanu
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
Download as pdf or txt
Download as pdf or txt
You are on page 1/ 53

Prepared by M.

Microprocessor and Assembly language programming Lab

Introduction to 8086 – Microprocessor architecture – Addressing modes - Instruction set and


assembler directives – Assembly language programming – Modular Programming - Linking and
Relocation - Stacks - Procedures – Macros – Interrupts and interrupt service routines – Byte and
String Manipulation.

8086 Microprocessor Addressing Modes Explained with Assembly Examples

This article contains information on 8086 microprocessor addressing mode and each addressing
mode is explained with examples.

What is Addressing Mode?

Addressing modes are different ways by which CPU can access data or operands. They determine
how to access a specific memory address. To load any data from and to memory/registers, MOV
instruction is used. The syntax of MOV instruction is:

MOV Destination, Source

It copies the data of 2nd operand (source) into the 1st operand (destination). To access memory,
segment registers are used along with general-purpose registers.

If you don’t know about internal register of 8086 microprocessor, read this article:

8086 Microprocessor Architecture

There are seven addressing modes in 8086 processor. Now, we will discuss all of them in detail with
example assembly instructions.

1. Register addressing mode

This mode involves the use of registers. These registers hold the operands. This mode is very fast as
compared to others because CPU doesn’t need to access memory. CPU can directly perform an operation
through registers.

For example:

MOV AX, BL

MOV AL, BL

The above two instructions copy the data of BL register to AX and AL.

Example Assembly Code

The ORG 100h is a directive which tells the compiler how to handle the source code.
Prepared by M.K
ORG 100h

MOV AX,CX

ret

Output:

In this example, you can see a red box in the output. This red box indicates the content of AX and
CX registers. The content of both AX and CX registers are the same. Because the above example moves
the content of CX into AX register.

2. Immediate Addressing Mode

In this mode, there are two operands. One is a register and the other is a constant value. The register
comes quickly after the opcode.

For example:

The instruction MOV AX, 30H copies hexadecimal value 30H to register AX.
Prepared by M.K
The instructions MOV BX, 255 copies decimal value 255 to register BX.

You cannot use the immediate addressing mode to load immediate value into segment registers. To
move any value into segment registers, first load that value into a general-purpose register then add this
value into segment register.

Example Assembly Code

Let us suppose you want to store 320H into DS register.

ORG 100h

MOV AX,320H ;copies hexadecimal value 320h to AX

MOV DS, AX ;copies value of AX into DS

ret ;stops the program

Output

If 0320h is added directly into the DS register using MOV instruction, the compiler will generate an
error.

3. Direct Addressing Mode


Prepared by M.K
It loads or stores the data from memory to register and vice versa. The instruction consists of a
register and an offset address. To compute physical address, shift left the DS register and add the offset
address into it.

MOV CX, [481]

The hexadecimal value of 481 is 1E1. Assume DS=2162H then the logical address will be
2162:01E1. To compute physical address, shift left the DS register and add it to offset address. The
physical address will be 26120H + 1E1H=26301H. Hence, after execution of the MOV instruction the
contents of the memory location 26301H will be loaded into the register CX. The instruction MOV
[2481], CX will store the CX register content to memory location 26301H.

Example Code

ORG 100h

MOV AX, 2162H ;copies hexadecimal value 2162h to AX

MOV DS, AX ;copies value of AX into DS

MOV CX, 24 ;copies decimal value 24 into CX

MOV [481], CX ;stores the data of CX to memory address 2162:01E1

MOV BX, [481] ;load data from memory address 2162:01E1 into BX

RET ;stops the program

Output
Prepared by M.K

In this example, the red box indicates the hexadecimal value 18 and decimal value 24 is stored at
memory address 21801h.

4. Register Indirect Addressing Mode

The register indirect addressing mode uses the offset address which resides in one of these three
registers i.e., BX, SI, DI. The sum of offset address and the DS value shifted by one position generates a
physical address. For example:

MOV AL, [SI]

This instruction will calculate the physical address by shifting DS to the left by one position and
adding it to the offset address residing in SI. The brackets around SI indicates that the SI contain the
offset address of memory location whose data needs to be accessed. If brackets are absent, then the
instruction will copy the contents of SI register to AL. Therefore, brackets are necessary.

Example Code

ORG 100h

MOV AX, 0708h ;set AX to hexadecimal value of 0708h.


Prepared by M.K
MOV DS, AX ;copy value of AX to DS

MOV CX, 0154h ;set CX to hexadecimal value of 0154h.

MOV SI, 42Ah ;set SI to 42Ah.

MOV [SI], CX ;copy contents of CX to memory at 0708:042Ah

RET ;returns to operating system

Output

In the above example, the physical address is 07080 + 042A = 74AA. According to the little-endian
convention, the 074AA will store the lowest bytes of data i.e., 54 and the 074AB will store the most
significant bits of data i.e. 01.

5. Based Relative Addressing Mode

This addressing mode uses a base register either BX or BP and a displacement value to calculate
physical address.
Prepared by M.K
Physical Address= Segment Register (Shifted to left by 1) + Effective address

The effective address is the sum of offset register and displacement value. The default segments
for BX and BP are DS and SS. For example:

MOV [BX+5], DX

In this example, the effective address is BX + 5 and the physical address is DS (shifted left) + BX+5.
The instruction on execution will copy the value of DX to memory location of physical address= DS
(shifted left) +BX+5.

Example 1 Code

ORG 100h

MOV AX, 0708h ;set AX to hexadecimal value of 0708h.

MOV DS, AX ;copy value of AX to DS

MOV CX, 0154h ;set CX to hexadecimal value of 0154h.

MOV BX, 42Ah ;set BX to 42Ah.

MOV [BX+5],DX ;copy contents of DX to memory at 0708:042Fh

RET ;returns to operating system

Output
Prepared by M.K

Some other alternative codings for MOV DX, [BX+5] are:

MOV DX, 5[BX]

MOV DX, [BX]+5

The instructions given below will load the value from memory location to register.

MOV [BX+10], DX

Now, suppose the base register is BP. Then, in this case, the default segment would be SS. In the
above example, replace BX by BP. Now the physical address is equal to SS (shifted left) +BX+5 which
is equal to 742F.

Example 2 Code

ORG 100h

MOV AX, 0708h ;set AX to hexadecimal value of 0708h.

MOV DS, AX ;copy value of AX to DS

MOV DX, 0154h ;set DX to hexadecimal value of 0154h.


Prepared by M.K
MOV BP, 42Ah ;set BP to 42Ah.

MOV [BP+5],DX ;copy contents of DX to memory at 0708:042Fh

RET ;returns to operating system

Output

6. Indexed Relative Addressing Mode

This addressing mode is same as the based relative addressing mode. The only difference is it uses
DI and SI registers instead of BX and BP registers.

For example:

Given that DS=704, SI = 2B2, DI= 145

MOV [DI]+12, AL

This instruction on execution will copy the content of AL at memory address 7197 (7040 + 145 +
12)
Prepared by M.K
MOV BX, [SI]+10

This instruction will load the contents from memory address 7302 (7040 +2B2 +10) to register BX.

7. Based Indexed Addressing Mode

The based indexed addressing mode is actually a combination of based relative addressing mode
and indexed relative addressing mode. It uses one base register (BX, BP) and one index register (SI, DI).
For example:

MOV AX, [BX+SI+20]

The above instruction can also be written as:

MOV AX, [SI+BX+20]

Or

MOV AX, [SI][BX]+20

In this case, the physical address will be DS (Shifted left) + SI + BX + 20. Now, if we replace BX
with BP then the physical address is equal to SS (Shifted left) + SI + BX + 20.

Now, let us have a look on these two instructions:

MOV AX, [BX][BP]+20

MOV AX, [SI][DI]+20

Both expressions are illegal as this mode supports one base register and one segment register.

Example Code

ORG 100h

MOV AX, 0708h ;set AX to hexadecimal value of 0708h.

MOV SS, AX ;copy data of AX to DS

MOV DX, 0154h ;store hexadecimal value of 0154h in DX.

MOV BP, 42Ah ;store hexadecimal value of 42Ah in BP.

MOV DI, 213h ;store hexadecimal value of 213h inDI

MOV [BP+DI+20],DX ;copy contents of DX to memory address 0708:0651

RET ;stops the program


Prepared by M.K
Output

In conclusion, addressing modes are ways to access the operands. The programmer can use any of
these seven addressing modes depending upon the program.

8086 Data Transfer Instructions – Assembly Language Programming

In this article, we will see different types of data transfer instructions supported by the 8086
microprocessors. We will see the function of each instruction with the help of an assembly language
program. These are the instructions that transfer the data from source to destination. They include:

MOV, PUSH, POP, XCHG, XLAT transfer bytes, or words.

IN, OUT transfer input and output ports.

LEA, LDS, LES transfer addresses.

LAHF, SAHF, PUSHF, POPF transfer flag registers.

In the last tutorial, we have discussed 8086 addressing modes.


Prepared by M.K
8086 Microprocessor Data Transfer Instructions

All of these instructions are discussed in detail.

1. MOV Instruction

The MOV instruction copies a byte or a word from source to destination. Both operands should be of
same type either byte or a word. The syntax of this instruction is:

MOV Destination, Source

The destination operand can be any register or a memory location whereas the source operand can be
a register, memory address, or a constant/immediate. The 8086 MOV instruction supports the following
operands:

Source Destination Example

Reg Reg MOV AX, BL

Memory Address Reg MOV CX, [2341]

Reg Memory Address MOV [7012], AH

Immediate Reg MOV AL, 21C

MOV [2310],
Immediate Memory Address
37B2

Segment
Reg MOV AX, DS
Register

Segment
Reg MOV CS, CX
Register

The instruction MOV mem, mem is illegal. It is not possible to transfer data directly from one
memory location to another. Therefore, both source and destination operands cannot be memory address.
The MOV instruction does not affect any value in the flag register.

Example Assembly Code

Consider an example to understand the behavior of MOV instruction. In the code given below, a and
b are the variables. DB is used for storing byte and DW is used for storing a word (2 bytes).
Prepared by M.K
ORG 100h

MOV AX, a ;Set AX to 'a' variable

MOV CX, 712h ;Set CX to 712h

MOV DS, CX ;Copies value of CX into DS

MOV SI, 25 ;Set SI to 0019 (decimal value of 25)

MOV [105], 6Ah ;Sets memory address 02712:0069 to 6Ah

MOV 25[BP][SI], AX ;PA=SS(Shifted left)+a+BP+SI

;Copy data from AX to physical address(PA)

MOV DL, [BX]+6 ;Load data from PA=DS(Shifted left)+BX+6 to DL

RET ;stops the program

a DW 5C21h

Output:
Prepared by M.K

The memory block has four columns. First column is of offset address. Second and third column
shows the hexadecimal value and decimal value stored in that offset address. The last column indicates
the ASCII character value. The 6th instruction in the code stores the hexadecimal value 6Ah at Physical
address 07189 (07120h + 0069h). In the 7th instruction, the value of AX is stored at physical address
07032 (07000h+0032h). The instruction MOV DL, [BX]+6 loads the value from memory location 07126
into DX shown in figure (3).
Prepared by M.K

2. 8086 PUSH Instruction

The PUSH instruction pushes the data in the stack. The format of PUSH instruction is:

PUSH Source

It decrements the stack pointer by two and then stores the data from the source operand at the
position of the stack pointer. The source operand can be a general-purpose register, segment register or a
memory address but it should be a word.

PUSH Assembly Code

The PUSH instruction decrements the SP by 2. You can see in the output the SP=FFFC which
decrements by 2 becomes FFFA. The data of AX is pushed to memory location DS: FFFA which is
16FFA in this example.

ORG 100h

MOV AX, 1C2Bh ;Set AX to 1C2B

PUSH AX ;Set SP=SP-2

;Push AX data to stack location DS:SP

MOV BX, 302Ah ;Set BX to 302A

PUSH BX ;SP=SP-2

;Push BX data to stack location DS:SP


Prepared by M.K
RET ;stops the program

Output

3. 8086 POP Instruction

It is opposite to the POP instruction. The POP instruction loads the word from the stack pointed by
SP and then increments the SP by 2. The format for this instruction is:

POP destination

The destination operand can be a general-purpose register, segment register, or memory address. The
POP instruction does not support CS as a destination operation.

POP Example Assembly Code

ORG 100h

MOV AX, 1C2Bh ;Set AX to 1C2B

PUSH AX ;Set SP=SP-2

;Push AX data to stack location DS:SP


Prepared by M.K
MOV BX, 302Ah ;Set BX to 302A

PUSH BX ;SP=SP-2

;Push BX data to stack location DS:SP

POP CX ;Load the last value stored at stack into CX which is BX

;increment SPby 2 i.e., SP=SP+2

POP [12H] ;Load the value from location of SP to memory address DS:0012H

;increment SP by 2

RET ;stops the program

4. Operand Exchange Instruction (XCHG)

The XCHG instruction exchanges the contents of the source and destination. Both operands should
be of the same type either word (16 bits) or a byte (8 bits). It does not support segment registers. The
direct exchange of data between memory locations is illegal. Both operands should be a general-purpose
register. The syntax of instructions is:

XCHG Destination, Source

For example

XCHG AX, BX exchanges words

XCHG AL, BL exchanges bytes.

XCHG CL, 25[BX] exchanges bytes of CL with bytes stored in memory location DS:25+BX.

XCHG CS, AX is illegal.

Example Assembly Code

ORG 100h

MOV AX, a ;Set AX to 'a' variable

MOV CX, b ;Set CX to 'b' variable

XCHG AX, CX ;Exchange words of AX and CX

XCHG AH, CL ;Exchange bytes of AH and CL


Prepared by M.K
RET ;stops the program

a DW 5C21h

b DW 3D05h

Output

The code given above first sets AX to 5C21 and CX to 3D05.

AX 5C21 CX 3D05

AH 5C CH 3D

AL 21 CL 05
Prepared by M.K
After execution of fourth instruction XCHG AX, CX, the contents of AX and CX are exchanged.
AX becomes CX and CX becomes AX.

AX 3D05 CX 5C21

AH 3D CH 5C

AL 05 CL 21

Then XCHG AH, CL exchanges the most significant bits of AH with lower bits of CL. The final
output becomes:

AX 3D05 CX 5C21

AH 21 CH 5C

AL 05 CL 3D

Just like MOV instruction, the XCHG instruction does not modify the contents of flag register. The

5. XLAT Instruction

The XLAT instruction takes no operands. It is used in lookup tables. The BX register contains the
offset address of the lookup table. The AL register has a byte number. The XLAT instruction takes the
byte number from AL and load the contents of address DS: BX+AL into AL register. The syntax for this
instruction is:

XLAT

or

XLAT Table_Name

First, you’ll have to store the starting offset address of table into BX register which is done by:

MOV BX, OFFSET Table_Name

Example Assembly Code

Now, consider an example which takes a variable a in a range 1 to 15 and display it as a hexadecimal
digit. We have taken a=13.

ORG 100h
Prepared by M.K
.MODEL SMALL

.DATA

TABLE DB '0123456789ABCDEF'

a DB 13

.code

MOV AL,a ;AL stores the byte number

MOV BX,OFFSET TABLE ;Sets BX to offset of starting address of the table

XLAT ;Sets AL to the hexa decimal value of var a

MOV DL,AL

MOV AH,02H ;Displays the charachter stored in DL

INT 21H

MOV AH,4CH

INT 21H

RET ;stops the program

Output
Prepared by M.K

6. 8086 I/O Port Data Transfer Instructions

These two instructions are supported by 8086 microprocessors to take directly transfer data between
GPIO ports.

IN Instruction

The IN instruction takes the input from the port and transfers that data into the register. Thus, data
transfer takes place between register and I/O device. The syntax of IN instruction is:

IN Reg, Port Address

The range of port addresses is from 000H to FFFFH.

IN AX, 29H

If you want to access a port number over 255 then first load the port address into DX and then use IN
instruction.

MOV DX, FA32H

IN AX, DX
Prepared by M.K
OUT Instruction

The OUT instruction outputs the data of register on to a port specified in the instruction. The syntax
of this instruction is:

OUT Port Address, Register

Example

OUT 26H, AL

If you want to use port address over 255, then store this port address to DX and then execute OUT
instruction

MOV DX, 456DH

OUT DX, AX

LEA Instruction

The LEA stands for load Effective address. As the name implies, it takes the data from the source
and copies it to the destination operand. The destination is always a register whereas the source can be an
offset address of a variable or a memory location. Both MOV and LEA instructions copy data from
source to destination but the difference between them is LEA copies only offset address or a memory
address to destination register. The syntax of LEA instruction is:

LEA Reg, Source

For example:

LEA AX, [BX] Stores the offset address of BX into AX.

LEA CX, var_1 Stores the address of var_1 into CX register

LEA BX, [BP][SI] Loads effective address = BP+SI into BX register

Example Assembly Code

ORG 100h

.MODEL SMALL

.DATA

VAR DB 23h

.code

MOV AX,@DATA ;Sets AX equal to the starting address of data segment


Prepared by M.K
MOV DS,AX ;Copy AX to DS

LEA DX,VAR ;Loads the address of VAR

RET ;stops the program

Output

In this example, you can see in the memory block, the offset address of variable VAR is 0102h
which is stored in DX after execution of LEA instruction.

LDS Instruction

The LDS instruction stores four consecutive memory locations into a specified destination register
and a DS register. The format of LDS instruction is:

LDS Reg, Memory Address

The word from first two memory locations is loaded into a register and the word from the next two
memory locations gets stored to DS register.

Example Assembly Code


Prepared by M.K
ORG 100h

.MODEL SMALL

.DATA

VAR DB 23h

.code

LDS AX,VAR

RET

Output

You can observe from the output that the address of variable var is 07012. The words from 07102h,
07103h locations gets stored into AL and AH. The contents of other two memory addresses 07104h and
07105h are loaded into DS.
Prepared by M.K

8086 LES Instruction

This instruction is almost similar to the LDS instruction. It loads data from first two memory
locations to a specified register. The data of the next two memory location goes to ES register. The
syntax of LES instruction is:

LES Reg, Memory Address

Example Assembly Code

ORG 100h

.MODEL SMALL

.DATA

NUM DB 5Ch

.code

LES SI,NUM

MOV AX,0710H

MOV DS,AX

LES BX,[8H]

RET

Output:
Prepared by M.K

The memory address of Num variable is 7102h. The instruction “LES SI, Num” sets SI to C45C and
ES to 0236. The next instruction “LES BX, [8H]” sets BX to 0710 and ES to D88E.

Other 8086 Data Movement Instructions

11. LAHF

The LAHF instruction loads the lower 8 bits of the flag register into AH register. The lower eight
bits of flag register includes SF, ZF, AF, PF and CF flags. It does not require any operand.

12. SAHF

The SAHF instruction stores the 8-bit data of AH register into the lower 8 bits of the flag register. It
has no operands.

13. PUSHF

It pushes the contents of flag register onto the top of stack. The PUSHF instruction decrements the
stack pointer by two and then store the data of flag register at location pointed by stack pointer (SP).

14. POPF

It pops the data from the first two memory locations pointed by stack pointer into the flag register
and then increment SP by 2. The POPF instruction has no operands.
Prepared by M.K
8086 assembler tutorials for beginners (part 3)

Variables

Variable is a memory location. For a programmer it is much easier to have some value be kept in a
variable named "var1" then at the address 5A73:235B, especially when you have 10 or more variables.

Our compiler supports two types of variables: BYTE and WORD.

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. It's possible
to declare unnamed variables by not specifying the name (this variable will have an address
but no name).

value - can be any numeric value in any supported numbering system (hexadecimal, binary, or
decimal), or "?" symbol for variables that are not initialized.

As you probably know from part 2 of this tutorial, MOV instruction is used to copy values from source to
destination.
Let's see another example with MOV instruction:

ORG 100h

MOV AL, var1

MOV BX, var2

RET ; stops the program.

VAR1 DB 7

var2 DW 1234h
Prepared by M.K

Copy the above code to the source editor, and press F5 key to compile it and load in the emulator. You
should get something like:

As you see this looks a lot like our example, except that variables are replaced with actual memory
locations. When compiler makes machine code, it automatically replaces all variable names with
their offsets. By default segment is loaded in DS register (when COM files is loaded the value
of DS register is set to the same value as CS register - code segment).

In memory list first row is an offset, second row is a hexadecimal value, third row is decimal value,
and last row is an ASCII character value.

Compiler is not case sensitive, so "VAR1" and "var1" refer to the same variable.

The offset of VAR1 is 0108h, and full address is 0B56:0108.

The offset of var2 is 0109h, and full address is 0B56:0109, this variable is a WORD so it occupies 2
BYTES. It is assumed that low byte is stored at lower address, so 34h is located before 12h.

You can see that there are some other instructions after the RET instruction, this happens because
disassembler has no idea about where the data starts, it just processes the values in memory and it
understands them as valid 8086 instructions (we will learn them later).
You can even write the same program using DB directive only:
Prepared by M.K

ORG 100h

DB 0A0h

DB 08h

DB 01h

DB 8Bh

DB 1Eh

DB 09h

DB 01h

DB 0C3h

DB 7

DB 34h

DB 12h

Copy the above code to the source editor, and press F5 key to compile and load it in the emulator. You
should get the same disassembled code, and the same functionality!
As you may guess, the compiler just converts the program source to the set of bytes, this set is
called machine code, processor understands the machine code and executes it.
ORG 100h is a compiler directive (it tells compiler how to handle the source code). This directive is
very important when you work with variables. It tells compiler that the executable file will be loaded
at the offset of 100h (256 bytes), so compiler should calculate the correct address for all variables when
it replaces the variable names with their offsets. Directives are never converted to any real machine
code.
Why executable file is loaded at offset of 100h? Operating system keeps some data about the
Prepared by M.K
program in the first 256 bytes of the CS (code segment), such as command line parameters and etc.
Though this is true for COM files only, EXE files are loaded at offset of 0000, and generally use special
segment for variables. Maybe we'll talk more about EXE files later.

Arrays

Arrays can be seen as chains of variables. A text string is an example of a byte array, each character is
presented as an ASCII code value (0..255).

Here are some array definition examples:

a DB 48h, 65h, 6Ch, 6Ch, 6Fh, 00h


b DB 'Hello', 0

b is an exact copy of the a array, when compiler sees a string inside quotes it automatically converts it to
set of bytes. This chart shows a part of the memory where these arrays are declared:

You can access the value of any element in array using square brackets, for example:
MOV AL, a[3]

You can also use any of the memory index registers BX, SI, DI, BP, for example:
MOV SI, 3
MOV AL, a[SI]

If you need to declare a large array you can use DUP operator.
The syntax for DUP:

number DUP ( value(s) )


number - number of duplicate to make (any constant value).
value - expression that DUP will duplicate.

for example:
c DB 5 DUP(9)
is an alternative way of declaring:
c DB 9, 9, 9, 9, 9
Prepared by M.K

one more example:


d DB 5 DUP(1, 2)
is an alternative way of declaring:
d DB 1, 2, 1, 2, 1, 2, 1, 2, 1, 2

Of course, you can use DW instead of DB if it's required to keep values larger then 255, or smaller then -
128. DW cannot be used to declare strings.

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.
LEA is more powerful because it also allows you to get the address of an indexed variables. Getting the
address of the variable can be very useful in some situations, for example when you need to pass
parameters to a procedure.

Reminder:
In order to tell the compiler about data type,
these prefixes should be used:

BYTE PTR - for byte.


WORD PTR - for word (two bytes).

For example:

BYTE PTR [BX] ; byte access.

or

WORD PTR [BX] ; word access.

assembler supports shorter prefixes as well:

b. - for BYTE PTR


w. - for WORD PTR

in certain cases the assembler can calculate the data type automatically.
Prepared by M.K

Here is first example:

ORG 100h

MOV AL, VAR1; check value


of VAR1 by moving it to AL.

LEA BX, VAR1; get address of


VAR1 in BX.

MOV BYTE PTR [BX], 44h ;


modify the contents of VAR1.

MOV AL, VAR1 ;


check value of VAR1 by moving it to
AL.

RET

VAR1 DB 22h

END

Here is another example, that uses OFFSET instead of LEA:

ORG 100h

MOV AL, VAR1; check value of VAR1


by moving it to AL.
Prepared by M.K

MOV BX, OFFSET VAR1 ; get address


of VAR1 in BX.

MOV BYTE PTR [BX], 44h ; modify


the contents of VAR1.

MOV AL, VAR1; check value of VAR1


by moving it to AL.

RET

VAR1 DB 22h

END

Both examples have the same functionality.

These lines:
LEA BX, VAR1
MOV BX, OFFSET VAR1
are even compiled into the same machine code: MOV BX, num
num is a 16-bit value of the variable offset.

Please note that only these registers can be used inside square brackets (as memory pointers): BX, SI, DI,
BP!
(see previous part of the tutorial).

Constants

Constants are just like variables, but they exist only until your program is compiled (assembled). After
definition of a constant its value cannot be changed. To define constants EQU directive is used:
Prepared by M.K
name EQU < any expression >

For example:

k EQU 5

MOV AX, k

The above example is functionally identical to code:

MOV AX, 5

You can view variables while your program executes by selecting "Variables" from the "View" menu of
emulator.

To view arrays you should click on a variable and set Elements property to array size. In assembly
language there are not strict data types, so any variable can be presented as an array.

Variable can be viewed in any numbering system:

HEX - hexadecimal (base 16).


Prepared by M.K
BIN - binary (base 2).

OCT - octal (base 8).

SIGNED - signed decimal (base 10).

UNSIGNED - unsigned decimal (base 10).

CHAR - ASCII char code (there are 256 symbols, some symbols are invisible).

You can edit a variable's value when your program is running, simply double click it, or select it and
click Edit button.

It is possible to enter numbers in any system, hexadecimal numbers should have "h" suffix, binary "b"
suffix, octal "o" suffix, decimal numbers require no suffix. String can be entered this way:
'hello world', 0
(this string is zero terminated).

Arrays may be entered this way:


1, 2, 3, 4, 5
(the array can be array of bytes or words, it depends whether BYTE or WORD is selected for edited
variable).

Expressions are automatically converted, for example:


when this expression is entered:
5+2
it will be converted to 7 etc...

8086 assembler tutorials for beginners (part 4)

Interrupts

Interrupts can be seen as a number of functions. These functions make the programming much easier,
instead of writing a code to print a character you can simply call the interrupt and it will do everything
for you. There are also interrupt functions that work with disk drive and other hardware. We call such
functions software interrupts.

Interrupts are also triggered by different hardware; these are called hardware interrupts. Currently we
are interested in software interrupts only.

To make a software interrupt there is an INT instruction, it has very simple syntax:

INT value
Prepared by M.K
Where value can be a number between 0 to 255 (or 0 to 0FFh),
generally we will use hexadecimal numbers.
You may think that there are only 256 functions, but that is not correct. Each interrupt may have sub-
functions.
To specify a sub-function AH register should be set before calling interrupt.
Each interrupt may have up to 256 sub-functions (so we get 256 * 256 = 65536 functions). In
general AH register is used, but sometimes other registers maybe in use. Generally other registers are
used to pass parameters and data to sub-function.

The following example uses INT 10h sub-function 0Eh to type a "Hello!" message. This function
displays a character on the screen, advancing the cursor and scrolling the screen as necessary.

ORG 100h ; instruct compiler to make


simple single segment .com file.

; The sub-function that we are using

; does not modify the AH register on

; return, so we may set it only once.

MOV AH, 0Eh ; select sub-function.

; INT 10h / 0Eh sub-function

; receives an ASCII code of the

; character that will be printed

; in AL register.

MOV AL, 'H' ; ASCII code: 72

INT 10h ; print it!

MOV AL, 'e' ; ASCII code: 101


Prepared by M.K

INT 10h; print it!

MOV AL, 'l'; ASCII code: 108

INT 10h ; print it!

MOV AL, 'l' ; ASCII code: 108

INT 10h ; print it!

MOV AL, 'o' ; ASCII code: 111

INT 10h ; print it!

MOV AL, '!' ; ASCII code: 33

INT 10h ; print it!

RET ; returns to operating system.

Copy & paste the above program to the source code editor, and press [Compile and Emulate] button. Run
it!

See list of supported interrupts for more information about interrupts.


1. SHL
SHL destination, count
This (Shift Logical Left) instruction performs the shift operation. The number of bits to be shifted is
represented by a variable count, either 1 or the number contained in the CL register.

Example
SHL AL, 1
Prepared by M.K
Before execution:
CF AL
0 1 1 0 0 1 1 0 0

After execution:
CF AL
1 1 0 0 1 1 0 0 0

2. SAL
SAL destination, count
SAL (Shift Arithmetic Left) and SHL (Shift Logical Left) instructions perform the same operation and are
physically the same instruction.
Example
SAL AL, CL
SAL AL, 1
3. SHR
SHR destination, count
Prepared by M.K
This (Shift Logical Right) instruction shifts the bits in the destination operand to the right by the number of
bits specified by the count operand, either 1 or the number contained in the CL register. Example SHR BL,
1 SHR BL, CL

The SHR instruction may be used to divide a number by 2. For example, we can divide 32 by 2,
MOV BL, 32 ; 0010 0000 (32)
SHR BL, 1 ; 0001 0000 (16)
SHR BL, 1 ; 0000 1000 (8)
SHR BL, 1 ; 0000 0100 (4)
SHR BL, I ; 0000 0010 (2)
9. SAR
SAR destination, count
This (Shift Arithmetic Right) instruction shifts the bits in the destination operand to the right by the
number of bits specified in the count operand. Bits equal to the original high-order (sign) bits are shifted
in on the left, thereby preserving the sign of the original value

Example :
SAR BL, 1
Before execution:
CF BL
0 1 1 0 0 1 1 0 0

After execution:
Prepared by M.K
0 1 1 1 0 0 1 1 0

10. ROL
ROL destination, count
This (Rotate Left) instruction rotates the bits in the byte/word destination operand to the left by the
number of bits specified in the count operand.

Example:
ROL AL, 1
Before execution:
CF AL
0 1 1 0 0 1 1 0 0

After execution:
CF AL

1 1 0 0 1 1 0 0 1

11. ROR
ROR destination, count
This (Rotate Right) instruction rotates the bits in the byte/word destination operand to the right by the
number of bits specified in the count operand.
Prepared by M.K

Example:
ROR AL, 1
Prepared by M.K
Before execution:
CF AL
0 1 1 0 0 1 1 0 0

After execution:
CF AL
0 0 1 1 0 0 1 1 0

12. RCL
RCL destination, count
This (Rotate through Carry Left) instruction rotates the contents left through carry by the specified
number of bits in count operand.

Example:
RCL AL, 1
Before execution:
CF AL
1 0 0 0 0 1 1 1 1

After execution:
CF AL
0 0 0 0 1 1 1 1 1

13. RCR
RCR destination, count
This (Rotate through Carry Right) instruction rotates the contents right through carry by the specified
Prepared by M.K
number of bits in the count operand.
Prepared by M.K

Example:
RCR AL, 1
Before execution:
CF AL

1 1 1 0 0 0 0 1 0

After execution:
CF AL
0 1 1 1 0 0 0 0 1

String Instructions

1. REP
Prepared by M.K
REP MOVS destination, Source
This (Repeat) instruction converts any string primitive instruction into a re-executing loop. It specifies a
termination condition which causes the string primitive instruction to continue executing until the
termination condition is met. REP is used in conjunction with the MOVS and STOS instructions.
Example:
REP MOVS CL, AL
The other Repeat instructions are:
REPE - Repeat while Equal
REPZ - Repeat while zero
REPNE - Repeat while Not Equal
REPNZ - Repeat while Not Zero
The above instructions are used with the CMPS and SCAS instructions.
Example:
REPE CMPS destination, source
REPNE SCAS destination
2. MOVS
MOVS destination - string, source-string
This (Move String) instruction transfers a byte/word from the source string (addressed by SI) to the
destination string (addressed by DI) and updates SI and DI to point to the next string element.
(DEST) ← (SRC)
Example:
MOVS Buffer 1, Buffer 2
3. CMPS
CMPS destination-string, source-string
This (Compare String) instruction subtracts the destination byte/word (addressed by
DI) from the source byte/word (addressed by SI). It affects the flags but does not affect the
operands. -.
Prepared by M.K

Example:
CMPS Buffer 1, Buffer 2
4. SCAS
SCAS destination-string

• This (Scan String) instruction subtracts the destination string element (addressed by DI) from the
Prepared by M.K
contents of AL or AX and updates the flags.
• ‘The contents of destination string or accumulator are not altered.
• After each operation, DI is updated to point to the next string element
Example:
SCAS Buffer
5. LODS
LODS source-string
This (Load String) instruction transfers the byte/word string element addressed by SI to register AL or
AX and updates SI to point to the next element in the string.
(DEST)←(SRC)
Example:
LODSB
nam
e LODSW
name
6. STOS
STOS destination - string
This (Store String) instruction transfers a byte/word from register AL or AX to the string element
addressed by DI and updates DI to point to the next location in the string.
(DEST) ← (SRC)
Example: STOS display
Program Transfer Instructions
Unconditional instructions : CALL, RET, JMP
Conditional instructions : JC, JZ, JA
Iteration control instructions : LOOP, JCXZ
Interrupt instructions : INT, INTO, IRET
1. CALL
• CALL procedure - name
• This (CALL) instruction is used to transfer execution to a subprogram or procedure.
• RET (return) instruction is used to go back to the main program.
• There are two basic types of CALL : NEAR and FAR
Prepared by M.K
Intra-Segment CALL:
• A NEAR-CALL is a call to a procedure which is in the same code segment as the CALL instruction.
• When 8086 executes a NEAR-CALL instruction, it decrements the stack pointer (SP) by 2 and copies
Prepared by M.K
the offset of the next instruction after the CALL on the stack.
• It loads IP with the offset of the first instruction of the procedure in same segment.
• This NEAR-CALL is known as Intra-segment CALL.
Inter-Segment CALL:
• A FAR-CALL is a call to a procedure which is in a different segment from that which contains the
CALL instruction.
• When 8086 executes a FAR-CALL, it decrements the SP by 2 and copies the contents of the CS register
to the stack.
• It then decrements SP by 2 again and copies the offset of the instruction after the CALL to the stack.
• Finally it loads CS with the segment base of the segment which contains the procedure and IP with the
offset of the first instruction of the procedure in that segment.
• This FAR-CALL is known as Inter-segment CALL.
Example:
CALL NEAR
CALL AX
2. RET
This (Return) instruction will return execution from a procedure to the next instruction after the CALL
instruction in the main program.
If intra-segment, IP is popped off the stack; SP =SP+2 If
inter-segment, CS is popped off the stack; SP = SP+2
IP is popped off the stack; SP=SP+2
If optional POP value is used, then SP= SP + value.
Example:
RET
RET 6
3. JMP
JMP target
This (Jump) instruction unconditionally transfers control to the target location. The target operand
may be obtained from the instruction itself (direct JMP) or from memory or a register referenced by
the instruction (indirect JMP). A NEAR-JMP (Intra-segment) is a jump where destination location is in the
same code segment. In this case only IP is changed.
Prepared by M.K
IP = IP + signed displacement
A FAR-JMP (Inter-segment) is a jump where destination location is from a different segment. In this case
both IP and CS are changes as specified in the destination.
Example:
JMPBX
Conditional JMP

Instruction Operation
JC Jump if carry
JNC Jump if no carry
JZ Jump if Zero
JNZ Jump if not zero
JS Jump if sign or negative
JNS Jump if positive
JP/JPE Jump if parity/parity even
JNP/JPO Jump if not parity/odd parity
JO Jump if overflow
JNO Jump if no overflow
JA/JNBE Jump if above/not below or equal
JAE/JNB Jump if above or equal/not below
JB/JNAE Jump if below/not above or equal
JBE/JNA Jump if below or equal / not above
JG/JNLE Jump if greater/not less than nor equal
JGE/JNL Jump if greater or equal/not less than
JL/JNGE Jump if less/neither greater nor equal
JLE/JNG Jump if less than or equal / not greater

5. LOOP

LOOP label
This (Loop if CX not zero) instruction decrements CX by 1 and transfers control to the target operand if
CX is not zero. Otherwise the instruction following LOOP is executed.

If CX≠0, CX = CX - l
Prepared by M.K
IP = IP + displacement
If CX=0, then the next sequential instruction is executed.
Example:
LOOP again
6. LOOPE/LOOPZ

LOOPE/LOOPZ label
These (LOOP while Equal/Loop while Zero) are different mnemonics for the
same instruction.

If CX≠0, CX=CX-1 and control is transferred '.o the target operand If CX = 0, then next sequential
instruction is executed. Example:

LOOPE again
7. LOOPNE/LOOPNZ

LOOPNE Label
These (LOOP while Not Equal/LOOP while Not Zero) are different mnemonics for the same
instruction. CX is decremented by 1 and control is transferred to target operand if CX is not zero and if
ZF=0; otherwise the next sequential instruction is executed.
Example:
LOOPNE again
8. JCXZ
JCXZ Label
This (Jump if CX register Zero) instruction transfers control to the target operand if CX=0. It is useful at
the beginning of a loop to bypass the loop if CX=0.
Example:
JCXZ again
9. INT
INT interrupt type (0-255)
This (Interrupt) instruction activates the interrupt procedure specified by the interrupt-type number
(0- 255). The address of the interrupt pointer is calculated by multiplying the interrupt-type number by 4.
Example :
INT 7, INT 180
Prepared by M.K

10. INTO
This (Interrupt on Overflow) instruction generates a software interrupt if the
overflow flag is set.
Otherwise, control proceeds to the following instruction without activating an
interrupt procedure.
11. IRET
This (Interrupt on Return) instruction transfers control back to the point of
interruption by popping IP, CS and the flags from the stack.

IRET is used to exit any interrupt procedure, whether activated by hardware or


software.
Processor Control Instructions
1. HLT
This (Halt) instruction will cause the 8086 to stop fetching and executing
instructions. The 8086 will enter a halt state. The ways to get the processor out of
halt state are with (i) an interrupt signal on the INTR pin.
(ii) An interrupt signal on the NMI pin, (iii) a reset signal on the RESET pin.
2. WAIT
This (Wait) instruction causes the 8086 to enter the wait state while its test line is
not active.
3. LOCK
• The LOCK prefix allow 8086 to make sure that another processor does not
take control of the system bus while it is in the middle of a critical instruction
which uses the system bus.
• The LOCK prefix is put in front of the critical instruction.
• When an instruction with a LOCK prefix executes, the 8086 will assert its bus
lock signal output. This signal is connected to an external bus controller device
which then prevents any other processor from taking over the system bus.
4. ESC
✓ This (Escape) instruction provides a mechanism by which other
coprocessors may receive their instructions from the 8086 instruction
stream and make use of the 8086 addressing modes.
Prepared by M.K

✓ The 8086 does a no operation (NOP) for the ESC instruction other
than to access a memory operand and place it on the bus.
5. NOP
This (No operation) instruction causes the CPU to do nothing. NOP does not affect
any flags.

You might also like