0% found this document useful (0 votes)
226 views

Assembly Lab Manual

This document provides an introduction to assembly language programming, including: - An overview of the fetch-decode-execute cycle of instruction execution and the role of microcode. - Descriptions of common instruction types (arithmetic, logic, data movement, control flow, etc). - Details on instruction encoding and various addressing modes. - An explanation of the 8086 architecture including registers, flags, stacks, and interrupts.

Uploaded by

Alicia Johnston
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
226 views

Assembly Lab Manual

This document provides an introduction to assembly language programming, including: - An overview of the fetch-decode-execute cycle of instruction execution and the role of microcode. - Descriptions of common instruction types (arithmetic, logic, data movement, control flow, etc). - Details on instruction encoding and various addressing modes. - An explanation of the 8086 architecture including registers, flags, stacks, and interrupts.

Uploaded by

Alicia Johnston
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 16

ASSEMBLY LANGUAGE PROGRAMMING: A LAB MANUAL

Contents

• Introduction
• Intel 8086: A brief excursion
• Using DEBUG
• Using the Assembler
• A sample program
• Data Definition
• Interrupts
• Functions
• Macros
• Interfacing

Appendix-I

Suggested list of experiments

Appendix-II

Note to the T.A / Instructor


ASSEMBLY LANGUAGE PROGRAMMING: AN INTRODUCTION

Instruction Execution

Fetch/Decode/Execute cycle is like a program:

• Repeat
• Fetch instruction from primary memory
• Increment Program Counter
• Decode
• Fetch operands from memory (if required)
• Execute instruction
• Write results to memory (if required)
• Until Halt
• How is this "program" written?

eg. ADD Instruction

1. Fetch operand1, store in register X


2. Fetch operand2, store in register Y
3. Tell ALU to add X and Y
4. Put result in ACC

MICROCODE (see fig. below)

• Lowest level of software


• Flexible: can be updated by designers
• Controls the digital logic of the CPU
• Implements the machine code instructions

Lowest level of software meets highest level of hardware


IS MICROCODE ESSENTIAL?

• Don't have to use microcode at all .


• Possible for Machine Code instructions to control logic directly (via Control
Unit)

Advantages

• Bug fixes are simpler than changing logic


• Complex instructions are best implemented as microcode

Disadvantages

• Instruction execution less efficient than "hard-wired" approach

INSTRUCTIONS

• Each type of CPU has it s own Instruction Set


• The set of instructions that can be decoded and executed
• Each instruction has a number
• Usually written as a "mnemonic"

8086 instruction set (79 basic instructions)

AAA AAD AAM AAS


ADC ADD AND CALL
CBW CLC CLD CLI
CMC CMP CMPS CMPXCHG
CWD DAA DAS DEC
DIV ESC HLT IDIV
IMUL IN INC INT
INTO IRET/IRETD Jxx JCXZ/JECXZ
JMP LAHF LDS LEA
LES LOCK LODS LOOP
MOV MOVS LOOPE/LOOPZ LOOPNZ/LOOPNE
MUL NEG NOP NOT
OR OUT POP POPF/POPFD
PUSH RCL RCR PUSHF/PUSHFD
REP REPE/REPZ RET/RETF REPNE/REPNZ
ROL ROR SAHF SAL/SHL
SAR SBB SCAS SHL
SHR STC STD STI
STOS SUB TEST WAIT/FWAIT
XCHG XLAT/XLATB XOR

TYPES OF INSTRUCTION

• Instructions vary from one CPU to another


• General groupings possible...
• Arithmetic/Logic

* Add, subtract, AND, OR, shifts


* Performed by ALU

• Data Movement

* Load, Store (to/from registers/memory)

• Transfer of Control

* Jump, Branch, procedure call

• Test/Compare

* Set condition flags

• Input/Output

* In, Out

* Only on some CPU's

• Others

* Halt, NOP

INSTRUCTION ENCODING

• Instruction defined by Opcode and Operands


• Decoded by examining bit patterns
• If operands used, must specify addresses

• Zero-address instruction: Opcode

• One-address instruction:

Opcode Address

• Two-address instruction:
Opcode Address1 Address2

• Instruction Length may be shorter than/ same as / longer than a machine


word

ADDRESSING

• Operands may be
o implicit (eg. stored in accumulator or on stack)
o stored in
 registers
 primary memory
 Instruction may need to specify addresses of operand(s) and where to put result
 Several ways to interpret address part of instruction (call it addr)

ADDRESSING MODES

addr is address field of instruction

 Immediate
addr is operand
 Register
addr is number of CPU register
operand := [ addr ]
 Direct
addr is address in primary memory
operand := [ addr ]
 Indirect
addr is register number (or memory address)
operand_address := [ addr ]
operand [ operand_address ]
 Indexed
addr is base address
index is a register

operand := [ addr + [index] ]

Auto-indexing modes allow automatic increment (or decrement) of value in index


register.

8086 ARCHITECTURE :Hardware Overview


PROGRAMMER'S VIEW - REGISTERS

The Registers

In Intel Processors there are several registers, the registers are special memory locations
that are built right into the chip. These registers are used to mess with data in a program.
All registers can and always work with numbers. The range of numbers that can be
loaded into a register is -65535 to +65535, I think, in hex the range is -FFFF to +FFFF
and finally in binary the range is -11111111 to +11111111. In the Intel processor there
are 4 general use registers:

AX - Called the Accumulator, used in math operations.

BX - Called the Base Register?, not used very often.

CX - Called the Count Register, used as a counter in loops.

DX - Called the Data Register, it just holds data.

All these registers can be split into 2 registers that hold a lower range of numbers. The
range for the split registers is: up to 255 decimal, FF in hex, and 1111 binary. Their
names are derived from the register they were split from:

AX: Contains AH and AL.


BX: Contains BH and BL.
CX: Contains CH and CL.
DX: Contains DH and DL.

When a split register is changed, the large register is changed as well. Example below:
Each split register is in fact PART of the original register it came from. So, if AX is
FF56 in hex. Then AL will be FF and AH will be 56. If you change a split register, you
also change that part of the large register.

The Special Registers

There are also 6 other registers in the Intel Processor. These have special uses too.
However, modifying these registers without knowing what you are doing can crash your
program, or your computer. They are called the Segment Registers:

CS - Code Segment, points to the segment of the currently running program code.

ES - Extra Segment, you can use this one!

DS - Data Segment, points to the segment of data to be used with certain operations.

SS - Stack Segment, points to the stack of the running program code.

For the other two they are NOT Segment Registers and are the most dangerous to mess
with:

BP - Base Pointer, points to the base of the stack.

SP - Stack Pointer, points to the top of the stack.

When a register points to something, that means if read the register will contain the
memory address of what it points to. Also these registers have the same range as the
regular registers, but CANNOT BE SPLIT UP.

The FLAGS

The FLAGS are a set of indicators that can have a TRUE (binary 1) or FALSE (binary 0)
value in them. They are modified through the use of set (make 1) and clear (make 0)
operations. They are also modified by any compare operation done. They are used as
error indicators too. They are:

Overflow Flag - Indicates that a number has gone too high to handle.

Carry Flag - Used as an error indicator, or holds the carry from an + or - operation.

Interrupt Flag - Indicates whether or not interrupts are honored or not.


Learn about interrupts later.

Parity Flag - Not used very often, it used to be used to indicate errors but nowadays...

Direction Flag - Used to determine which way text operations work.

Trap Flag - Of no use to us.

Sign Flag - Indicates an above or below after the comarison of numbers.

Zero Flag - Indicates an equal result after a compare operation.

Auxiliary Flag - Of little use to us.


Those are all the flags, as you can see some are leftover from the early days of Intel
Processors and aren't used any more by programmers. These flags are a necessity for a
certain operation I'm not going to tell you about yet. However, flags are very important,
don't ever forget them!

The Stack

The stack is just a bunch of data that gets stacked on top of each other growing downward
in memory. When a register or all of the flags gets pushed onto the stack, the stack grows
down. When a value is popped off the stack the value popped is the last one that got
pushed on. LIFO: Last In First Out, remember that because that is how the stack works.

Interrupts

They Interrupt the CPU. Interrupts are just what the name suggests, they interrupt the
processor (CPU from now on) and make it do something and then return to
what it was doing before the interrupt. There are several kinds of interrupts,
they are:

Hardware - Internal CPU interrupts, we can't use these.

Software - One of the most important things to use.

Each interrupt has a unique number, and each interrupt number has many function
numbers that determine the interrupt function to run. Next section we start coding!

Using Interrupts

To use an interrupt function you need a function number in the AH split register. And
then you call the interrupt number that contains the function. Here is an example:

mov ah,4ch ; MOVes 4C in hex to AH.


int 21h ; calles the DOS System interrupt number.

Function 4C of int 21h is the end program function, this function is why programs
crashed if you ran assembled code from previous sections. Some functions require
parameters to be passed to them. Parameters are required to be passed in registers.
Registers used for parameters differ from function to function. Here is an example:

mov ah,2 ;MOVes 2 to AH. 2 is the write letter to screen


function.
mov dl,'H' ; DL is where the letter goes. Letters are specified in
quotes.
int 21h ; 21h is the DOS service interrupt number.
mov ah,4ch
int 21h ; These last two line are to make it work if you
assemble it.

Some functions return one or several values in registers, such as one letter input functions
and so on.
8086 ADDRESSING

• Address bus: 20 bits... 1,048,576 addresses


• But internal registers only 16 bits: can't hold a full address
• Segment Registers define four 64k "windows" on the address space

8086 addresses are specified as xxxx:yyyy

o where xxxx is value in segment register


o yyyy is offset

Addresses are specified as relative to start of segment

eg. Instruction Pointer relative to Code Segment

Address of next instruction (hexadecimal) is:

CS xxxx0
IP yyyy +
---------
Addr aaaaa

aaaaa is "effective address" (20 bits)

Put another way:

effective address = 16 * [ segment-reg ] + offset

(Referred to as segment/offset addressing)

Most other microprocessors can access all of memory at any time: "flat memory
model"
8086 FEATURES

• Segment/offset addressing
o addresses are relative to segment registers
o segments may overlap
• Storage is Little-Endian
• 8086 CPU is split into two main parts
o Execution Unit
 General Registers
 ALU
o Bus Interface Unit
 Instruction Queue
 Segment Registers
 Instruction Pointer
• Status Flags Register

O = Overflow Z = Zero
D = Direction A = Aux. Carry
I = Interrupt P = Parity
T = Trap C = Carry
S = Sign

A Machine Code Program


addr code
0000 2B C0
0002 03 07
0004 83 C3 02
0007 3B D3
0009 79 F7

• 2B C0 =0010 1011 1100 0000


• Format of register-to-register instruction:

opcode = 001010 means "Subtract"


w = 1 means "word" (16 bits); 0 means "byte"
dest reg = address of destination register: 000 = AX
src reg = address of source register: 000 = AX
ASSEMBLY LANGUAGE PROGRAM

Written using mnemonics and comments

0000 SUB AX,AX ;Set AX to 0

0002 ADD AX,[BX] ;add (word pointed to by BX) to AX

0004 ADD BX,2 ;Add 2 to BX (points to next word)

0007 CMP DX,BX ;Compare DX to BX

0009 JNS 0002 ;If DX >= BX jump back to 0002

• Adds up contents of memory from [BX] to [DX], result goes in AX

CMP - COMPARE

• Subtracts source from destination and updates flags


• does not save result.
• Flags can subsequently be checked for conditions
• CMP DX, BX performs (DX - BX)
• So if BX > DX result will be negative - Sign bit will be set
• Test/Compare instructions set flags
• Flags may affect later instructions (eg. Conditional jumps)

JNS - JUMP IF NOT SIGNED

• Jumps to new address if Sign flag = 0

0009 79 F7 JNS 0002

• 79 means "JNS"
• How does "F7" take us back to 0002...?

F7 = 1111 0111

2's complement... MSB=1 so NEGATIVE


Invert: 0000 1000

Add 1: 0000 1001 = 9 (dec)

• Therefore 1111 0111 (F7) is -9

• After fetching "79 F7" Instruction Pointer = 000B


• Adding -9 to IP gives 0002

Start Coding

First, lets learn how to move data to a register:


To move data to a register you use the mov command. Where the data is to go is the first
item, and the data is the second item. Here is an example that MOVes 45 to AX:
mov ax,45

Let's try assembling it: Type mov ax,45 into asm.txt and save it. Drag asm.txt over
A86.com and drop it to assemble. A86.com will run and create 2 new files. The .sym file
is of no use to us and can be deleted. However, the .com file is the program. Don't try
running the .com file, because it WILL crash because we didn't end the program properly.
That is how to assemble a file.

Now, let's move data from one register to another: We still use the mov command , and
time the register to receive the data is first and the register with the data to move is
second, here is an example:
mov ax,45h
mov bx,ax
The first line moves 45(h after a number means hex) into ax, the second copies the
number in ax (45h) to bx, so bx is now 45h too. To mov data around in the split registers
simply replace the large register with the split version. Like this mov ah,cl or mov
dh,90h , however, do not mix large and split registers like this mov ah,ax or it won't
assemble. Using split registers works for add and sub only.

Math Operations

+,-,*,divide (how do you do divide on a keyboard?)

The basic math operations in assembly are:

add - Adds the first item to the second storing result in first item.

sub - Subracts the second item from the first and stores result in the first item.
mul - Multiplies the given item to AX and stores the result in AX.

div - Divides the given item by AX and stores the result in AX.

The add and subtract operations are simple enough, they do their job like a MOV
command and subtract or add to the receiving end and store the result in the receiving
end. Example:
add ax,23 ;adds 23 to ax and stores results in ax.
sub ax,45h ;subtracts 45 in hex from ax and stores in ax.

The mul and div instructions are a bit different though, they both use the AX register as
their "base of operations", They both multiply to or divide by A REGISTER ONLY and
store the result in AX.

example: MULTIPLICATION:
mov ax,10 ;give a value to multiply by in AX.
mov bx,20 ;give a register the data we want to * by
AX.
mul bx ;multiply ax & bx, storing the result in
AX.
example: DIVISION:
mov ax,10 ;What we want to divide or data by.
mov dx,100 ;What we want to be divided by AX.
div dx ;Divide DX by AX, storing result in AX.

And that's how the BASIC Math Operations work. That's right! Basic is italicized
because there are actually two more math operations I have not mentioned yet, and no,
they do not make multiply and divide any easier! Wondering why the explanations of the
example code start with semi-colons? Find out in the next section!

Code Comments

What those semi-colons are for! Those semi-colons are called code comments, they are
useful to document your code so you know what each thing does. The semi-
color (;) stops the assembler from thinking that your comment is assembly
code and returning an error. Comments last until the end of the current line
and are considered good programming practice in large projects. That's all the
commenting I have to comment on comments! :-)

Labels and Unconditional Jumps

The goto statement for you Basic Programmers. In this section we start getting into
program flow control. Labels are just what the name suggests labels, the
syntax for a label is like this:

example: label1:

As you can see it is a name and a colon. NO CODE CAN BE ON THE SAME LINE AS
A LABEL! Labels do not actually do anything but sit there and reference a location in a
program. However, they are very useful for Unconditional Jumps, which are used to
JUMP to another location in a program and run the code starting after the label
referenced. Here is an example to best explain Unconditional Jumps:
jmp runhere ;JMP command jumps to the label "runhere" and
run the code after it.
mov ax,45 ; This command won't be run because it is JMPed
over!
runhere: ; The label where the JMP jumps to.
mov ax,90h ; This statement will be run after the jump.

Now I hope that you understand labels and their use with Unconditional Jumps.

Conditional Jumps

Conditional Jumps only jump if a certain condition is met, that's why they are called
conditional! The condition they check is based on the FLAGS. See, I told you the flags
would be important! There are several jump commands that check a certain thing to see
if they should jump or not. They are:

JE - Checks for equality.

JNE - Checks for UNequality.

JA - Checks to see if one thing is Above another.

JB - Checks to see if one thing is Below another.

JZ - Same as JE...

Those are the Conditional Jump Commands. Use them well Young Jedi.

Compare Command

The Compare Command (CMP) compares the first item with the second setting and
clearing flags automatically. The most recent compare is what conditional jumps use.
You can compare two registers like this:
cmp ax,bx ;Compares AX to BX

And Register to Data like this:

cmp dx,45 ;Compares DX to 45

REMEMBER THAT CMP DOESN'T STORE ANYTHING!

Also, remember that the first item is compared TO the second. This command is like
telling the computer to create an equation resulting from the comparison such as DX >
45, which would make the JA (Jump on Above) jump. Remember in all operations that
registers go on the left and data goes on the right. You can also use the split registers
with the cmp command.
APPENDIX-I

SUGGESTED LIST OF EXPERIMENTS

1 [Arithmetic]
Write 8086 Assembly Language programs for the following operations. The
operands and the results are to be stored in specific memory locations.
(a) Add three 16-bit unsigned integers (b)Add three 16-bit signed integers (c)
Multiply two 16-bit unsigned integers (d) Multiply two 16-bit signed integers
(e) Divide a 16-bit unsigned integer by an 8-bit unsigned integer (f)Compute
the function:
X = |((A*B) – (C*D))| /E. Assume 16-bit unsigned integer variables.

2 [Basic Input/Output]
Study the various BIOS interrupts and DOS function calls that are useful in
input and output operations. Build programs for multiple character input,
multi-digit input, etc that may be reused in the subsequent programs.

3 [Control Structures ]
Write Assembly Language programs for simulating:
(a) For.. loop (b)While loop (c) Repeat..until loop (d) If ..then..else structure
(e)Switch statement ( of C language). Use appropriate action within the loop
such that the difference among the above control structures is understood.

5 [Subroutines -Use of Stack]


(a) Write a subroutine for raising an integer x to an integral power n. Using
this routine, evaluate a polynomial p(x) at x = k. (b)Test whether an input
string is a palindrome.

6 [Search]
(a) Write a program to search for a given number in an array of N numbers. Do
not assume that the array is sorted. Generate appropriate responses after a
success and failure (b) Create a sample login session for a user. Get a User-id
and Password from the keyboard, without echoing the password. Verify the
User-id, password pair using a stored list, and take appropriate action.

7 [Finding Min and Max of a set of numbers]


Given a set of N integers, find the minimum value in it. Without using an
additional loop, find the maximum value also. Hence find the range of the set
(i.e. Max-Min).

8 [Display Attributes and Speaker control]


Design a menu-driven program for the following display functions
(a) Clear the screen (b) Display the string given by the user at the center of
the screen in a particular color and make it blink (c) Produce a beep sound
after step b is completed.

9 [MACRO definition]

Code a MACRO definition to find the GCD of two integers. It should accept two
dummy parameters A and B and produce GCD (A, B). Use the macro for
finding LCM (A, B) also.

Exp 10 Interfacing
(a) Interface a Digital-to-Analog Converter (DAC) to the 8086-kit and write a
program to display different waveforms (triangular, square, saw tooth, etc) on
a CRO. (b) Interface a Stepper motor interface card to the 8086 kit, and write
a program to control the rotation of the stepper motor.

APPENDIX-II

NOTE TO THE T.A / INSTRUCTOR

• An introductory session to the functional blocks of Intel 8086, its


instruction set and the use of MASM/TASM/DEBUG is desirable.

• Divide the students into groups of 2-3 people. Assign each group a
user-id and password on a specific machine, which must be used
throughout the course.

• After login, go to the directory C:/8086/HELPPC on the C drive. Choose


MASM or TASM as the case may be. HELPPC contains the basics of
8086 architecture and its instruction set.

• Enter the programs using a text editor, and assemble using


TASM/MASM from the DOS command line. Link the .obj files and
execute the resulting .exe file. Alternately, use the debugger facility to
enter, assemble and step through the program.

• After completing each experiment, a demo of the same should be


evaluated. Also insist on regular record submission.

References

• IBM PC Assembly Language and Programming: Peter Abel

• Using Assembly Language: Wyatte, Sr.

You might also like