Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
143 views

8086 Assembly Language Programming

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
143 views

8086 Assembly Language Programming

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 26

1 Micro-processors

The component that does the data processing. Below is the 4-bit Intel 4004,
which was designed in 1971 as the main chip in a calculator.
8086 Assembly Language Programming

David Wilson

Overview of computing & PC Assembly language

 By itself, the micro-processor cannot do much,– it needs many sup-


S TUDENT V ERSION port chips (computers in themselves)

 Fabricated in silicon
Högskolan i Karlstad
 Many different types of micro-processors. Two are important, the
Karlstad, Sweden 8051 (micro-controller) and the 8088 (PC family)

1996 Computer micro-processor manufacturer


Original IBM (1980) 8088 Intel
Apricot (UK) 8086 Intel
IBM PC AT 80286 Intel
Apple Mac, Atari 68000 Motorola
Dec Alpha Alpha Digital (DEC)
PCs today 486/Pentium Intel or AMD etc

David Wilson U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
8086 Assembly Language Programming
1/52 K ARLSTAD 2/52 1 Micro-processors K ARLSTAD
Intel’s Pentium processor dye with an overlay to show which part of the
chip does what.
The start of a revolution
25 years ago in 1971, a small startup company manufacturing memory
chips were approached by Busicom, a Japanese company to make a calcu-
lator.

Instead they fabricated the world’s first microprocessor, the 4-bit Intel
4004. Later the same company produced the Pentium Pro.

4004 P ENTIUM P RO
Transistors 2,300 5,500,000
Die size 12mm2 196 mm2
Transistor size 10 m 0.35 m
Clock speed 750 kHz 200,000 kHz
MIPS rating 0.06 440
Memory capacity 4kb 64 Gb
Package size 16pins 387 pins

The internals of Intel’s 400-MHz P6 processor showning 7.5 million tran-


sistors on 0.35 m technology.

Clearly things have progressed a long way in just 25 years!

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
3/52 1 Microprocessors /2 K ARLSTAD 4/52 1 Pentium dye /3 K ARLSTAD
Megabyte (1 000 000 bytes)

1 Megabyte: A small novel OR A 3.5 inch floppy disk


2 Mb: A high resolution photograph
2 Data powers of 10 5 Mb The complete works of Shakespeare OR 30 seconds of TV-quality video

Quantities of data held by various media. Gives a good idea of rough 10 Mb A minute of high-fidelity sound OR A digital chest X-ray

magnitudes in terms we can understand. 20 Mb A box of floppy disks


50 Mb A digital mammogram
Good justification of why I need a bigger hard disk. 100 Mb 1 meter of shelved books OR A two-volume encyclopaedic book
200 Mb A reel of 9-track tape OR An IBM 3480 cartridge tape
500 Mb A CD-ROM OR The hard disk of a PC
Bytes (8 bits)
Gigabyte (1 000 000 000 bytes or 109 )
0.1 bytes: A binary decision
1 byte: A single character 1 Gigabyte: A pickup truck filled with paper OR A symphony in high-fidelity sound
OR A movie at TV quality
10 bytes: A single word
2 Gb: 20 meters of shelved books OR A stack of 9-track tapes
100 bytes: A telegram or A punched card
5 Gb: An 8mm tape
Kilobyte (1000 bytes) 20 Gb: A good collection of the works of Beethoven OR 5 Exabyte tapes OR A VHS
1 kilobyte: A very short story tape used for digital data

2 kb: A typewritten page 50 Gb: A floor of books OR Hundreds of 9-track tapes

10 kb: An encyclopaedic page or A deck of punched cards 100 Gb: A floor of academic journals OR A large ID-1 digital tape
Terabyte (1 000 000 000 000 bytes or 1012 )
50 kb: A compressed document image page
1 Terabyte: An automated tape robot OR All the X-ray films in a large technological hospital OR 50000 trees made into paper and printed OR Daily rate of
100 kb: A low-resolution photograph EOS data (1998)

2 Tb: An academic research library OR A cabinet full of Exabyte tapes


200 kb: A box of punched cards 10 Tb: The printed collection of the US Library of Congress

500 kb: A very heavy box of punched cards 50 Tb: The contents of a large Mass Storage System

Petabyte (1 000 000 000 000 000 bytes or 1015 )

? Note a kilobyte is really 210 = 1024 rather than a simple one thousand. 1 Petabyte: 3 years of EOS data (2001)

2 Pb: All US academic research libraries

20 Pb: Production of hard-disk drives in 1995

200 Pb: All printed material Production of digital magnetic tape in 1995

Exabyte (1 000 000 000 000 000 000 bytes or 1018 )

5 Exabytes : All words ever spoken by human beings.

Zettabyte (1 000 000 000 000 000 000 000 bytes)

Yottabyte (1 000 000 000 000 000 000 000 000 bytes)

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
5/52 2 Data powers of 10 K ARLSTAD 6/52 2 Data powers of 10 /2 K ARLSTAD
3 8088 architecture 4 8086 PC assembler
The organisation of the Intel 8088 used in the first IBM PCs. We can program the Intel 80x86 chip in assembler, although this is not
common nowadays.
Architecture of the 8088

Execution Unit (EU) Bus Interface Unit (BIU)

general registers
AX IP CS
BX
CX
- Temp DS
SS All the sophisticated cousins 80286, 80386, 486, Pentium, Klamath etc
registers
DX ES
BP 6 use the exact same instrucxtion set. (Except for MMX, multi-media in-
SP
 structions)
DI
? ?
SI
6 - adder
Programming assembler looks very similar:

 ? internal bus
? ? - MOV AX, 3 ; put number in 16bit register AX
66 6 6 ?Bus? ADD AX, 2 ; add 2 to AX
-  -
? ?  control Same general rule: operand, register#1, register#2.
 EU
 logic external bus
ALU Control
logic
 To compile and link an assembler program, you need an Assembler, and a
Linker; say M ASM and L INK.
instruction queue
flags  8086 16bit registers The early members of the 80x86 family were 16 bit
processors. Even today

 the 486s, pentiums etc when first powered up start in real mode, which
is similar to the original 8086 PC.

 When running MS-DOS, programs run in real mode, or are equivalent


to the original PC

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
7/52 3 8088 architecture K ARLSTAD 8/52 4 8086 PC assembler K ARLSTAD
Ref: Turbo C (ver 2.0) User’s Manual, Chpt 12.

8086 Registers overview (continued)


5 8086 Register map General purpose are the most commonly used when manipulating data.
However some have special uses:
The 8086 registers are similar to the accumulator on the 8051, but we have
more of them and they are 16bits wide, (or even 32 bits wide for ’386s).  Many mathematic operations must use AX
AX,BX,CX,DX ; general purpose, but some have special purposes, (ACC,  BX can be used to hold the offset portion of a far pointer
base, counter, data)  CX is used in the LOOP instruction
CS,DS,SS,ES ; code, data, stack & extra segment registers.  DX is used by certain instructions to hold data
SP,BP,SI,SI ; looping, stack pointers etc. Segment registers hold the starting address of each of the 4 segments;
(code, data, stack and extra). The address is shifted left 4 bits (16) to
Register map on the 8086/80186/80286
get the true 20 bit address. Segments must start at paragraph bound-
aries.
z }|
16 bits {
8 bits Special purpose registers can be used as general purpose, and:
8 z }| {
> 9  SI & DI can be used as index registers
> ax ah al accumulator >
=
>
> bx bh bl base
>
< cx
dx
ch
dh
cl
dl
count
data
>
;
data registers
 SP points to the current top-of-the stack, and is an offset into the
general registers
> sp stack pointer stack segment.
>
> bp base pointer
>
: si
di
source index
destination index
 The BP is a secondary stack pointer, usually used to index into
the stack in order to retrieve parameters.
8
>
< cs code segment
data segment
ds An understanding of these registers is necessary to understand the differ-
segment registers
>
: ss stack segment
es extra segment ences between the various memory models in T URBO C for example.
ip instruction pointer
flags

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
9/52 5 8086 Register map K ARLSTAD 10/52 5 8086 CPU /2 K ARLSTAD
Complete the following table:
AX BX CX DX We cannot mix these ‘new’ 8 bit registers with the old;
MOV AX, 5 5 ? ? ? MOV AL, CH ; ok since one 8-bit into another
MOV BX, 4 5 ? ? ? MOV AX, CL ; Not ok since on 8-bit into a 16 bit register !
SUB AX, 2 ? ? ? ? in one instruction, we must use entirely 8 bit registers, or all 16 bit registers.
MUL BX ? ? ? ?
Some operations have the source and destinations implied; e.g. multiplica- Conventions: Some other conventions for 8086 assembler language pro-
tion MUL BX means gramming:

[DX,AX] := AX  BX  Immediate constants do not have a # sign in 8086 assembler. The


‘address of’ symbol is [AX].

 Use decimal for immediate constants (unless you append an h or b)


The AX register is 16 bits wide. What is the maximum & minimum num-
bers allowed?  Start all hex numbers with a numeral, eg: 0F3Ah; (same as in the
16 8051)
2 = 65536 = 64K

so we can use numbers from 0 to 65535 (decimal), or 0xFFFF.  Don’t start in column #1, except for labels.
8-bit registers
Since we would like 8-bit compatability with many external devices, we
can use only the top half or the bottom half of the ‘X’ registers;
High & low 8 bit registers

AX 16 bits wide
z }| { z }| {
AH AL BH BL CH CL DH DL
8 high 8 low | {z }
8 bits wide

Now we are limited to 0xFF of 255d.

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
11/52 5 8086 assembler /3 K ARLSTAD 12/52 5 8086 assembler /4 K ARLSTAD
Other flags are:

CF (carry flag) Set whenever there is a carry out from bit 7 in an 8 bit
6 8086 Flags operation and bit 15 in a 16 bit operation.

PF (parity flag) After certain operations, the parity of the result’s low order
Flag register similar to the PSW in the 8051, except that there are more of
byte is checked. If the byte has an even number of 1s, the PF is set to
them.
1 otherwise it is cleared (set to 0).
The flag register is a special purpose 16 bit register. It has 5 arthmetic
flags (overflow, sign, zero, aux carry, carry) and others used in the 286 for AF (auxiliary carry flag) If there is a carry out from bit 3 (to bit 4), the flag
multitasking etc. is set, otherwise it is cleared (set to 0).
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
ZF (zero flag) This is set to 1 if the result of an arithmetic operation is 0,
R R R R OF DF IF TF SF ZF – af – pf – CF
otherwise it is cleared (set to 0).
OF overflow flag DF direction flag IF interrupt flag
TF trap flag SF sign flag ZF zero flag SF (Sign flag) After an arithmetic or logical operation, the sign bit of the
AF auxiliary carry flag PF parity flag CF carry flag
result is copied into the SF.

Carry CF (carry flag) Set whenever there is a carry out from bit 7 in an 8 TF (Trap Flag) When this flag is set it allows the program to single step.
bit operation and bit 15 in a 16 bit operation.
IF (Interrupt flag) This bit is set or cleared to enable or disable external
Conditional flags because they indicate some condition that resulted after maskable interrupt requests.
an instruction was executed.
DF (Direction flag) Used in string operations.
CF, PF, AF, ZF, SF and OF
OF (Overflow flag) Set whenever the result of a signed number operation
Control flags because they are used to control the operation of the instruc- is too large or too small causing th high order bit to oeverflow into the
tions before they are executed. sign bit.
TF, IF and DF

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
13/52 6 8086 Flags K ARLSTAD 14/52 6 8086 Flags /2 K ARLSTAD
7 Direct & indirect addressing 8 8086 jumps & loops
To be able to move data from memory, we need a way to address memory Jumps are possible (of course) in the 8086 instruction set. The 8086 has
or use pointers. many jump instructions (too many for practical use).
One important jump is JZ which means ‘jump if the previous instruction
Convention is different from the Intel 8051 di-
resulted in zero’.
rect/indirect techniques.
MOV AX, 3
Use square brackets for “the address of”. SUB BX, AX
MOV AL, [10h]; copy the contents of address 10hex into AL (one JZ miss_lots ; jump if zero
byte) INC DX ; otherwise carry on
MOV BX, [20h]; copy the contents of address 20hex and 21hex into
two byte BX reg. miss_lots MOV CX, DX
Also possible to store data from register to memory; NOP ; carry on anyway
MOV [20h], CL; copy register to memory. Again labels are a luxury given to us by the assembler. (Start with a letter
or an underscore, .
Incrementing & decrementing or increasing/decreasing by one. Problem
is whether we are talking about words or bytes. Loops: The 8086 has 18 kinds of conditional jumps! We will use the
INC AX; No problem, 0FC1 ! 0FC2 survival kit of just the following:
INC BL; No problem, 49 ! 4A 1. JMP straight jump
INC [BX]; illegal !, are we talking about a byte or a word ?
Or do we increment the word stored starting at the address stored in BX, 2. JZ jump if zero
or just the byte? 3. JNZ jump non-zero
Use the pseudo-ops to make your intentions clear
4. JA,JB jump if above/below (unsigned)
INC BYTE PTR [BX]; inc the byte stored at the address in BX
INC WORD PTR [BX]; inc word 5. JG,JL jump if greater/less than (signed)

The jumps depend on the flag setting. (This may not be what you expected,
remember the INC command in the 8051?)

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
15/52 7 Direct & indirect addressing K ARLSTAD 16/52 8 8086 jumps & loops K ARLSTAD
Loops are similar to 8051 but with more possibilities. One way is the
following:
MOV loop_counter, start_value ; store start value
start: CMP loop_counter, finish_value ; top of the loop 9 Segmented memory architecture
JA stop ; jump if finished
NOP Segmented memory architecture is a feature of the 8086. It has a total
NOP ; do the loop internals address space of 1Mb, but is designed to directly address only 64K of
INC loop_counter ; increase loop
memory at one time. A 64K chunk is known as a segment.

 The 8086 keeps track of 4 segments:


JMP start ; go back

stop: NOP ; finished loop, now


1. code, where the machine instructions are
This is long-winded, so we can use a special op-code, LOOP that uses the 2. data, where infomation lies
CX “counter” register. 3. stack
MOV CX, 23d ; store start value in CX 4. extra (usually not used, or if it is, is used for extra data)
start: -- ; top of the loop
-- ; loop internals  The 8086 has four 16bit registers (one for each segment), which point
to the start of each segment. (They must start on a paragraph bound-
LOOP start ; dec CX & JNZ to start
-- ; otherwise carry on ary.)

 Note that no flags are affected, and some ‘hidden’ operations occur.  Segments can (but do not have to) overlap. If all 4 occupy the same
64K segment, then you have a .com file.
 Other special loops op codes are LOOPZ, LOOPNZ, JCXZ
We can adjust the sizes and positions of these segments by using different
 All are short  127 bytes jumps memory models in T URBO C. Normally I use the small memory model.
 Test CX = 0 before you enter the loop, or you will do 65,000 itera-
tions since the DEC occurs first.

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
17/52 8 Loops /2 K ARLSTAD 18/52 9 Segmented memory architecture K ARLSTAD
8086 Address modes The 8086 is an 16-bit chip but has a 20 bit address
space. This means that we can use
Data segment
20 def When we store data, it will be relative to the data segment, DS.
2 = 1048576 = 1 Megabyte
MOV AL, [200h] ; actual memory is DS:0200h
On the early PCs running MS-DOS, we used 640kbytes + video memory. Means that we can just change the DS register, and quickly access different
To use 20 bit address lines, we need to use a segment and offset. memory (with the same instructions). Like register banks in the 8051.

20bits = F FFFF
| {z }
However we cannot directly access the DS register, (must go through the
2bytes BX register first)
MOV BX, 500h ; want DS to equal 500h
We split the address space into segements and then only worry about the
MOV DS, BX ; indirectly load DS
offset within each segement. (I.e. chapters & pages with in the chapter, or
months, and days within the month) MOV BH, [100h] ; store 5000 + 100 = 5100h

Segments are 0–FFFF hex (64k long) and we use the notation: Normally the operating system sets DS register to something sensible, and
<segment address: offset address> we are unlikely to want to change it.
For example, 3C04:BOA2 is
z seg
}| {
3C04 0
+ BOA2
| {z }
o
= 3DOE2
For code, we use CS:IP which means the instruction pointer in the current
code segment.

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
19/52 9 8086 address modes /2 K ARLSTAD 20/52 9 Segment & offset /3 K ARLSTAD
10 8086 Assemblers 8086 assembly using the W OLFWARE assembler.
A Listing file for a simple program, ex mul.asm, is given below. (You
To compile assembler code into an executable, we need an Assembler pro- have only types the right-hand side).
gram. The choices for the are:
Ex_mul.Asm -- Page 1
 Use debug from the old versions of MS-DOS (not user-friendly) 12:43 pm, April 8, 1997

 Look on the internet for public domain and/or demo versions: Loc Obj Line Source Wasm 2.02

– Wolfware shareware Assembler, (WASM202.ZIP) 1 ; FILE: ex_mul.asm


2 ; compile c:> wasm ex_mul.asm,, ex_mul.lst
http://ftp.urz.uni-
3
heidelberg.de/ftp/pub/msdos/simtel/asmutl/ 0100 B00F 4 MOV AL, 0FH, ; store some numbers
0102 B306 5 MOV BL, 6 ; immediate constants
– Light Macro Assembler; 0104 B108 6 MOV CL, 8
http:www.tamasoft.co.jp/lasm/index-e.html 0106 B20C 7 MOV DL, 0CH

 Commerical Borland Turbo Assembler & debugger, TASM


8
0108 B600 9 MOV DH, 0 ; pad with zero

 Commerical Microsoft Assembler, MASM


10
010A 28CB 11 SUB BL,CL ;

 Use the ‘built-in’ assembler in T URBO C. (Not advisable since you


010C F6EB 12 IMUL BL; ax := ax*bl
010E F7EA 13 IMUL DX; DX,AX := 00DL*AX
lose some of the features) 14
15 ; finished code, so return to DOS
0110 B8004C 16 MOV AX, 04C00H
We also need a linker (if we are going to produce EXE files rather than
0113 CD21 17 INT 21H
COM files) & possibly a debugger. 18 ; end of code ...................

 B ORLAND Turbo Debugger (commercial) and linker 19

 M ICROSOFT linker. 0
19
Error(s) detected
Line(s) processed
21 Byte(s) of code
0 Symbol(s) defined
Note that the program starts at 0100h.

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
21/52 10 8086 Assemblers K ARLSTAD 22/52 10 Writing 8086 assembly in Wolfware /2 K ARLSTAD
To compile the assembler code, ex mul.asm, use the W OLFWARE as-
sembler, wasm.
c:\WASM> wasm ex_mul,,ex_mul.lst
11 Writing raw 8086 assembly language programs
Wolfware Assembler 2.02
The exact details of a ‘raw’ assembly language program depend on the
Source = Ex_mul.Asm environment. The following is for B ORLAND Turbo Assembler. (It is
Object = Ex_mul.Com
List = Ex_mul.Lst
better than WASM.)

No errors detected 1. Write your assembler source file in a normal editor.


c:\WASM> ex_mul.com ; Turbo Assembler Skeleton
.MODEL small
c:\WASM> .STACK 100h
.CODE
; place instructions here
You will generate an executable COM file, which you can then run. However
you won’t see anything! mov ah,4ch ; DOS terminate program function
int 21h ; terminate the program

 Very simple programs (limited to .com and 64k code & data) END

 Note the location & objext code in the listing file. (Extreme left hand- I normally use the small memory model for assembler programs.
side.) 2. TASM /l /zi filename.asm
 The code always starts at 0100hex offset. The segement for a COM This generates an .obj file from the assembler source with a listing
file is decided by DOS. file and full debugging info.

 Similar to the 8051 listing files. (Turn off the debugging info when you are finished since it makes a smaller executable,
and is harder to reverse-engineer.)

Debug the assembler using the DOS debug command. (This may not be
available, depends on your DOS version.) 3. TLINK /v filename
Better (commercial) debuggers exist such as TDEBUG from Borland. Create the .exe file and include the debugging info.

4. Run the debugger, TD filename or execute the code.

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
23/52 10 Assembler progs /3 K ARLSTAD 24/52 11 Writing raw 8086 assembly language programs K ARLSTAD
Assembler Example: A simple program to do some arithmetic statements; The debugger window (in DOS) looks just before the subtraction instruc-
tion.
6 ,8
0x??0F , (6 , 8)

Our source is:


; Turbo Assembler
; ARITH.ASM - Do some simple arithmetic statements & re-
turn to DOS
; Compile with: tasm /zi /l filename.asm
; Link with: tlink /v filename

.MODEL small
.STACK 100h
.CODE
mov al, 0fh ; load some immediate constants
mov bl, 6
mov cl,8
mov dl,0Ch

sub bl,cl ; Subtract CL from BL


imul bl ; ax := ax*bl

mov ah,4ch ; DOS terminate program function


int 21h ; terminate the program Note:
END
1. Source code is to the left
The (small) sizes of the files are:
File Size (bytes) 2. CPU registers are to the right. Look at the IP register
Raw Debug info 3. Other windows such as the CPU window (not shown) are possible.
Assembler 496 –
Object 217 375 4. Watch window shows us the DL register.
Executable 528 1202

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
25/52 11 Assembler example /2 K ARLSTAD 26/52 11 Running the debugger /3 K ARLSTAD
File sizes
Assembler has the potential to produce very small executable files. This is
12 8086 Interrupts Thorne, p542
important for the embedded system universe where RAM & ROM is still
an economic necessity. The size of a minimal file to print “Hello, World” Interrupt philosophy is similar to the Intel 8051. They
to the screen are:

C language version Assembler language version

#include <stdio.h> ; Display the mes-



main()
sage "Hello World"
.MODEL small

{ .STACK 100h
printf("Hello, World\n"); .DATA
What happens when an interrupt occurs? The processor automatically
return 0; HelloMessage DB ’Hello, world’,13,10,’$’
} .CODE
mov ax,@data 1. saves the instruction pointer CS:IP on the stack
mov ds,ax ;set DS to point to the data se
mov ah,9 ;DOS print string function 2. saves flags on stack
mov dx,OFFSET HelloMes-
sage ; point to str 3. jump to a special memory location depending on the type of interrupt
int 21h ;display string
mov ah,4ch ;DOS terminate (See next OH)
int 21h ;terminate
END
The address to jump to is calculated by jumping to the address con-
tained in the next 4 bytes starting from address:
File C executable ASM executable
Size (bytes) 8669 543 interrupt type  4
Question The assembler code is only 6% of the HLL version. Why is the
4. proceed until IRET, not reti, then
C program so much bigger ?
5. POP CS:IP and the flags from the stack, and return back there.

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
27/52 11 Assembler file sizes /4 K ARLSTAD 28/52 12 8086 Interrupts K ARLSTAD
8086 interrupts
All first 100h (256d) memory locations have interrupt vectors for DOS
& BASIC reserved. Various types of interrupts are described below, find
others in the documentation. 13 DOS services using Interrupt 21h
# address description DOS functions. As you have seen, so far our assembler program cannot do
0 0–3 division by zero much. But we can make use of operating system calls to easily do things
1 4–7 single-step (for debugging) like:
2 8–B non-maskable interrupt
4 overflow  read the keyboard
5 print screen  writing to the terminal
9 keyboard
15 cassette input/output !  read & write to a floppy disk
1C timer strobe (20ms)  write to ports
21 DOS function calls
40–7F user interrupts  Exit back to DOS
We have 0 to 0FFh interrupt possibilities. The processor jumps to the ad- These are all done via a special interrupt, or INT 21h. To use, do the
dress = interrupt type4 and then takes the next 4 byte address of the following
interrupt service routine. 1. Put the special code in the AH register (Look up in the DOS technical
Example If interrupt 21h occurs, then the processor jumps to address con- reference manual for these, or on the internet)
tained in 84h to 87h,
2. call INT 21h
INT 21h - 84H 85H 86H 87H Look at the final 2 lines in the assembler code to return to DOS.
? ? ? ?  changes with DOS version
| {z }| {z }
offset segment

If the trap flag is set, and interrupt will occur after every instruction! Good
for debugging & and using C ODE V IEW.

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
29/52 12 8086 interrupts /2 K ARLSTAD 30/52 13 DOS services using Interrupt 21h K ARLSTAD
Example of a simple C program to assembler is:
; Compile: tcc -Ldirectory - which compiles to: (some material omitted
S c2asm.c here)
main()
14 Compiling C to Assembler { _TEXT segment byte pub-
int a,b; lic ’CODE’
Obviously if we are to compile a C source, we probably pass through an ;
a=3; ; main()
intermediate assembler stage. It is instructive to look at the automatically
b=a+5; ;
generated assembler source by the compiler. Why? return 0; assume cs:_TEXT
} _main proc near
push bp
Note: mov bp,sp
 The C source is retained as com- sub sp,4
ments in the assembly code ;
; {
 The compiler chooses its own ‘inter-
; int a,b;
esting’ labels
; a=3;
 Some supurfulous instructions such ;
as short jumps to the next line! mov word ptr [bp-
2],3
;
; b=a+5;
;
In B ORLAND Turbo C, use the -S compiler option to only go as far as mov ax,word ptr [bp-
assembler. (You must use this from the commmand line.) In my case, I 2]
add ax,5
use: mov word ptr [bp-
c:> tcc -Lc:|borland|bc|lib -S filename.c 4],ax
;
; return 0;
;
xor ax,ax
jmp short @1@58
@1@58:
;
; }
;
mov sp,bp
pop bp
ret
_main endp

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
31/52 14 Compiling C to Assembler K ARLSTAD 32/52 14 C to assembler /2 K ARLSTAD
Turbo Pascal function returns, but these may not be standard.
When Turbo Pascal returns from a function, it will store the answer in the
following registers: T URBO C has a similar return convention.
15 Mixed language programming: Assembler & Pascal
Function type Registers
Ref: Tom Swan, Mastering Turbo Pascal Boolean,Char AL
enumerated (8-bit) AL
Often device drivers and interfacing needs to be done in assembler, but you
enumerated (16-bit) AX
would rather write the rest of the program in Pascal.
shortint, byte AL
Writing assembler & a Pascal program, you have the following 3 options: integer,word AX
longint DX=high, AX=low
1. Write inline code in assembler inside a Pascal routine. Horrible
real DX=high, BX=mid, AX=low
since you will need to do the machine translation yourself!)
pointer DX=segment, AX=offset
2. Write with the asm keyword. (New versions only, and will not allow
you to do loops, macros etc.) Co-processor types, single,double are more complicated.
8086 stack
3. Write an external assembler module, and declare it as an external
function Snapshot of a stack frame during a typical procedure

I prefer the latter because it ‘hides’ the assembler code, and is better from high memory
a software engineering point of view. (You also must use a commerical
assembler & linker.) , SP before & after calling procedure
9
=
[BP+04],!
param
; passed word
return
[BP+02],!
address
, SP at entry
BP
, BP during procedure 9
>
>
[BP-02],!
v2 >
=
>
>
local variables
v1 >
;
[BP-04],! , SP during procedure
low memory

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
33/52 15 Mixed language programming: Assembler & Pascal K ARLSTAD 34/52 15 Assembler & Pascal /2 K ARLSTAD
Pascal main program must define the externally available object file. Oth- Assembler part is compiled and stored to disk as an object file.
erwise the Pascal compiler does not know about the function. Note the compile directives I use. (You could use something different)

1. Write your Pascal program as normally ; File: STDEM.ASM (Stack demo)


COMMENT *
2. Write and compile to object code your external (assembler) function, From Shell.ASM for external Procedures & Func-
tions for Turbo Pascal
say tfunc.obj For TASM or MASM and Turbo Pascal ver 4.0, 5.0, & 5.5

3. Include the f$L STDemg line to tell the compiler where to find
Ref: Tom Swan "Mastering Turbo Pascal ver 5.5" p506-508
Compiling instructions:
tfunc.obj. Also include function prototype. TASM /zi /l filename.asm ; generate debug & listing
*
4. Compile & run
DATA SEGMENT WORD PUBLIC
We will call an assembler subroutine, tfunc that behaves as if it was a thePort dw ? ; Comm port number for example
DATA ENDS ; end of data segment
standard Pascal subroutine.
program STdem; CODE SEGMENT WORD PUBLIC
{ Test linking to an external TASM procedure ASSUME CS:CODE, DS:DATA
Ref: Tom Swan, p509 PUBLIC tfunc
The following line must appear at the start } ;-----------------------------------------------------------
; Function tfunc(byte1,byte2:byte) : word
{$L STDem} { Link the following routines in STDEM.OBJ} tfunc PROC NEAR ; Use FAR if compiled with {$F+} or in Unit
push bp ; save base pointer
FUNCTION tfunc(a,b:byte) : byte ; EXTERNAL; {external obj file} mov bp,sp ; address parameters with bp
;--------- user code starts here
Var a,b : byte; xor AX, AX ; clear AX and BX registers
rc : word; xor BX, BX
begin { Start main program } ; load passed parameters LIFO
a := $15 ; {input byte} mov BL, Byte Ptr [bp+04] ; 2nd parame-
b := 12; {2nd passed argument} ter passed into function
rc := tfunc(a,b) ; {external assembler function} add BX, 10H
writeln(a,b,rc) mov AL, Byte Ptr [bp+05] ; 1st parameter passed
end. add AX, BX ; return word by default
;--------- user code ends here
mov sp, bp ; restore stack pointer
pop bp ; restore bp
ret ; return, release additional bytes ?
tfunc ENDP

CODE ENDS ; end of code segment


END ; end of text

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
35/52 15 Pascal main code /3 K ARLSTAD 36/52 15 Assembler part /4 K ARLSTAD
Pascal & assembler

 Note that I repeat the Pascal definition (as a comment) in the ASM 16 Mixed language programming (C & ASM)
code for reference.
Writing C programs which can call, (and be called by), assembler subrou-
 I use this ‘skeleton’ for all my routines tines is a useful task. This is similar to PASCAL and assembler, but slightly
? Preserve the stack the way you found it! more complicated because C is more flexible.

 Store the answer in the correct registers (see previous table). Reasons to program parts in assembler:

 When compiling, if you include a map, then debugging is easier.


The general procedure is similar for C (see OHs following).

There are 2 ways to pass parameters into a subroutine. We can use either,
but the C method is preferred.

1. C parameter method.
Slightly slower than the Pascal method.

2. Pascal passing method.


Not as robust, cannot pass a variable number of parameters, called
routine must know how many will be passed.

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
37/52 15 Pascal & assembler /5 K ARLSTAD 38/52 16 Mixed language programming (C & ASM) K ARLSTAD
C passing sequence Assembler skeletons If you are going to write ‘real’ .exe files in as-
We have a function prototype in C: sembler using either TASM or M ASM, then you should use the following
void funca(int p1, int p2, int p3); skeleton:
When funca is called, the parameters are pushed onto the stack in right-
; My stand-alone assembler program for MASM
to-left order, (p3,p2,p1). So if
DATA SEGEMENT (pseudo op)
i = 5; j = 7; k = 0x1407AA Place definition of data items here
then with funca(i,j,k), the stack will look like DATA ENDS; end of data segment
SP+06: 0014 WORKINGSTORAGE SEGEMENT STACK
SP+04: 07AA k = p3 DW 100h DUP(?) ; programs requirement for storage (stack)
SP+02: 0007 j = p2
SP: 0005 i = p1 WORKINGSTORAGE ENDS

Since the stack grows from high memory to low memory, i, is currently at
CODE SEGEMENT
the top of the stack.
ASSUME DS:DATA, SS:WORKINGSTORAGE, CS:CODE
The routine being called does not know exactly how many parameters have
been pushed on to the stack. All it assumes is that the parameters are there. MOV ax, bx; copy bx into ax
put code here . . .
..
.

CODE ENDS; end of code segment


With simple assemblers such as Wasm we do not need separate code and
data segments, (since it only compiles to .COM files), but we do with
M ASM or TASM.

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
39/52 16 C passing sequence /2 K ARLSTAD 40/52 16 Assembler skeletons /3 K ARLSTAD
17 Memory models 18 Small memory segmentation
T URBO C has 6 memory models, for efficiency reasons. Choose the small- Traditionally the small memory model under DOS was drawn this way,
est you can get away with, normally small.

Tiny All 4 segments are in the same address, 64K for all code, data &
arrays. NEAR pointers used. Can convert to .COM files.
Segment registers
Low Memory CS - Segment Size

TEXT class ‘CODE’ up to 64K


Small Code & data do not overlap, 64K for each. NEAR pointers used. 8- 9
DS,SS
>
> >
>
>
> >
>
Medium,Compact NEAR for one, FAR pointers for the other < DATA class ‘DATA’
>
initialised data >
>
Large, Huge FAR pointers used for both code & data.
DGROUP
>
> >
>
>
: DATA class ‘DATA’ =
You should read the manual for the diagrams of the memory segmentation.
uninitialised data >
>
up to 64K
>
>>> Free space
HEAP
SP (top of stack) - >
>
;
Library routines are different for each memory model. It is convenient
-
STACK
Starting SP
to copy the relevant library files into your working directory (although not
 up toFree
FAR HEAP the rest of memory
space
strictly necessary) High Memory

Model libraries required


Tiny c0t.obj, maths.lib, cs.lib But there are sources of confusion in this diagram:
Small c0s.obj, maths.lib, cs.lib  Low address are at the top of the figure!
Compact c0c.obj, mathsc.lib, cc.lib
Medium c0m.obj, mathsm.lib, cm.lib  Do segments ‘grow down’, or ‘shrink up’?
Large c0l.obj, mathsl.lib, cl.lib So refer to the next OH for the (revised) memory map for the small model.
Huge c0h.obj, mathsh.lib, ch.lib

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
41/52 17 Memory models K ARLSTAD 42/52 18 Small memory segmentation K ARLSTAD
(A better) illustration of the small memory model.

64K DGROUP 64K Available RAM


z }| {z }| {z }| { 19 Calling conventions
Ref: Tom Swan, ‘Mastering Borland C++ ver4.5’, p785
TEXT DATA BSS STACK
segment segmentsegment segment
HEAP STACK When we write mixed language programs, we must first understand how
‘CODE’ ‘DATA’ ‘BSS’
‘STACK’
we can pass parameters, pointers, structures back and forth from one rou-
code data data heap
- free
 -
stack far heap free tine to another.
6 6 6 For this we use the stack. But we have two conventions to do this:
cs ds,ss sp
Low addresses high addresses Pascal calling convention reduces code size, but only permits a fixed num-
ber of parameters to be passed. Used by PASCAL, and MS Windows
 TEXT segment ‘CODE’ refers to the symbol & name assigned to the and C if you use the pascal keyword.
compiled segment.
C calling convention pushes arguments onto the stack before calling the
 DGROUP is an assembly language term that groups multiple segments routine, after which the caller removes to prevent the stack from over-
together. flowing. Permits a variable number of arguments to be passed.

 Segment registers point to the base address of the relevant segment. In all cases, these issues are partly compiler/OS dependant, so it is best to
In the small model, the data & extra segments are the same.
inspect the assembly of an ‘empty’ function. Not protected for upgrades.
 The SP points to the top of stack which moves in the direction of the
arrow.

 Small memory models give the best possible speed advantage.

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
43/52 18 Small memory (revised) /2 K ARLSTAD 44/52 19 Calling conventions K ARLSTAD
Inline assembler code (in Borland Turbo C).
Writing inline code is the easiest way to write small chunks of assembly
in your own programs. You use the key word asm which when compiled
20 External ASM routines in C
calls the built-in assembler.
Ref: Tom Swan, ‘Mastering Borland C++ ver4.5’, p798–801
 No macros (unlikely that you will want them for small routines any-
way) Timer count: Application to access the computer’s internal timer count

 Cannot assemble 386 and 486 specific instructions


stored at address 0000:046Ch.

 Cannot use lables (At least my old version couldn’t, but new versions
/* C program which calls assembler */
#include <conio.h>
can jump to C lables outside asmf...g statments.) extern long Timer(); // assembler routine

 Does not recognise a special mode for Borland’s assembler, IDEAL main()
{
mode. while (!kbhit()) {

 Only a limited set of directives available for reserving memory gotoxy(1,wherey());


cprintf("%1d ",Timer()); // call timer here

 Requires annoying non-standard commment delimiters and new state- }


getch(); // throw away keypress
ment delimiters (to be partly compatible with the surrounding C code) return(0); // return to dos
}
Writing asm statements inside a C source code. Note the extra features
& comment delimiters! Note in the above C program;

/* Inline assembler for Borland 4.5 */  that the assembler routine is declared to be external, and returns a
long integer (4 bytes).
asm {
push bp // save bp on stack extern long Timer();

 The function Timer has a dummy C prototype, but no internals.


mov bp, sp // set bp equal to sp
push ax; push bx; push cx ; push dx /* do all one 1 line! */

pop bp // clean up  C routine is compiled as a small memory model. (Not visible. but
} use the -ms comiler flag for memory model (small).)

 Stack not used in Timer routine, and no input parameters are passed.

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
45/52 19 Inline code /2 K ARLSTAD 46/52 20 External ASM routines in C K ARLSTAD
Assembler routine (written in Borland IDEAL mode). There are small syntax Compiling C and assembler & linking external routines
differences for Microsoft M ASM.
1. Compile the C program testtime.c to an object file (Use the -c
; Timer routine to be called from C flag)
IDEAL ; Ideal mode for TASM
MODEL small 2. Assemble the .asm program timer.asm to an object file
CODESEG 3. Link both object files together to create an executable.
PUBLIC _Timer
Or you could do all 3 steps in one from the command prompt:
PROC _Timer ; procedure starts here
xor ax,ax ; clear AX c:> tcc -Lc:\borland\bc\lib -Ic:\borland\bc\include test-
mov es,ax time.c timer.asm
mov di, 0046cH ; address of timer
mov ax, [WORD PTR es:di] ; move count into AX Turbo C++ Version 3.00 Copyright (c) 1992 Borland International
mov dx, [WORD PTR es:di+2] ; and DX testtime.c:
ret timer.asm:
ENDP ; end of procedure Turbo Assembler Version 3.2 Copyright (c) 1988, 1992 Bor-
land International
END
Assembling file: timer.ASM
 Memory model is SMALL, same in the C program Error messages: None
Warning messages: None
 No DATA segment is needed (or declared) Passes: 1
Remaining memory: 387k
 Lable of assembler routine is declared PUBLIC with a leading under-
Turbo Link Version 5.1 Copyright (c) 1992 Borland International
score added, Timer and is case sensitive.

 Variables exported in [DX,AX] Available memory 4109104


Now run the executable, testtimer.exe
 No name ‘mangling’ for C codes, (but does occur for C++, see man- If you want debug infomation, use the -v compiler flag.
ual for further details)

Now we need to combine both the C program & the assembler into a single
executable.

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
47/52 20 External assembler routine /2 K ARLSTAD 48/52 20 Compiling & linking the routines /3 K ARLSTAD
Make files allow one to define projects and conditional compilations. Use-
ful for ‘professional’ projects. My make file shown below shows:
21 Interrupts in assembler
1. Defines symbols for inlcude libraries
Interrupts can now be serviced in C (but this is non-standard, and was not
2. Specifies dependancies always the case)
3. Gives DOS command lines to do the compiling & linking.

See manual for further uses.


Make file: casm.mak for DOS.

# Make file for Turbo Make 3.6


# Filename: casm.mak
# c:> make -fcasm.mak

library=c:\borland\bc\lib
include=c:\borland\bc\include

testtime.exe: testtime.obj timer.obj


tcc -L$(library) -I$(include) testtime.obj timer.obj
testtime.obj:
tcc -c -L$(library) -I$(include) testtime.c
timer.obj:
tasm timer.asm

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
49/52 20 Make files /4 K ARLSTAD 50/52 21 Interrupts in assembler K ARLSTAD
22 New 8086 architecture, MMX 23 Summary
From Jan 1997, Intel have announced the first new instructions for the A couple of quotes:
80x86 line of processors since the ’386. They are called MMX or (multi-
media extensions). “Frederick P. Brooks in “The Mythical Man Month” speculates
all speed problems can be solved by translating one to five per-
 Single instruction, multiple data cent of a program into optimised assembly language. Optimising

 backwardly compatible the rest of the program is likely to produce negligible results.”

 Uses the floating point unit registers, so cannot be used together with From Tom Swan, p825
the FPU.
Choosing a Memory Model
 Penalty in switching from FPU to MMX and back again. “The great myth about memory models is that, by selecting a
 Ideal for integer processing, image processing, discrete Cosine trans- larger model, you give your programs extra RAM. Nonsense.
forms (DCT) used in jpegs & mpegs compression coding Under DOS, al memory is available to all programs in all mem-

 Speeds these (practical) tasks up by about a factor of 2 at best. ory models. A memory model simply changes the methods that
the compiler and you can use to address data and to call func-
In the floating point unit, we have eight 80-bit registers. The MMX unit tions. A memory model is an addressing scheme, not a memory
takes these over and turns them into eight 64bit packed registers. supplier.”

Each register has either 8 bytes, 4 words, two 32 bit double words, or one
single 64bit quad word.
Single instruction, multiple data The new packed addition instruction
will add all 8 byte operands in one register to another 8 bytes in one go.
Speed increase of 8.
Or use packed addition on two sets of four words. Speed increase is 4.
But there is no test for overflow, just saturation or wrap around!.

David Wilson 8086 Assembly Language Programming U NIVERSITY OF David Wilson 8086 Assembly Language Programming U NIVERSITY OF
51/52 22 New 8086 architecture, MMX K ARLSTAD 52/52 23 Summary K ARLSTAD

You might also like