ZeePedia

Preface

Introduction to Assembly Language Programming >>
Preface
Assembly language programming develops a very basic and low level
understanding of the computer. In higher level languages there is a distance
between the computer and the programmer. This is because higher level
languages are designed to be closer and friendlier to the programmer,
thereby creating distance with the machine. This distance is covered by
translators called compilers and interpreters. The aim of programming in
assembly language is to bypass these intermediates and talk directly with the
computer.
There is a general impression that assembly language programming is a
difficult chore and not everyone is capable enough to understand it. The
reality is in contrast, as assembly language is a very simple subject. The
wrong impression is created because it is very difficult to realize that the real
computer can be so simple. Assembly language programming gives a
freehand exposure to the computer and lets the programmer talk with it in
its language. The only translator that remains between the programmer and
the computer is there to symbolize the computer's numeric world for the ease
of remembering.
To cover the practical aspects of assembly language programming, IBM PC
based on Intel architecture will be used as an example. However this course
will not be tied to a particular architecture as it is often done. In our view
such an approach does not create versatile assembly language programmers.
The concepts of assembly language that are common across all platforms will
be developed in such a manner as to emphasize the basic low level
understanding of the computer instead of the peculiarities of one particular
architecture. Emphasis will be more on assembly language and less on the
IBM PC.
Before attempting this course you should know basic digital logic
operations of AND, OR, NOT etc. You should know binary numbers and their
arithmetic. Apart from these basic concepts there is nothing much you need
to know before this course. In fact if you are not an expert, you will learn
assembly language quickly, as non-experts see things with simplicity and the
basic beauty of assembly language is that it is exceptionally simple. Do not
ever try to find a complication, as one will not be there. In assembly language
what is written in the program is all that is there, no less and no more.
After successful completion of this course, you will be able to explain all
the basic operations of the computer and in essence understand the
psychology of the computer. Having seen the computer from so close, you
will understand its limitations and its capabilities. Your logic will become fine
grained and this is one of the basic objectives of teaching assembly language
programming.
Then there is the question that why should we learn assembly language
when there are higher level languages one better than the other; C, C++,
Java, to name just a few, with a neat programming environment and a
simple way to write programs. Then why do we need such a freehand with
the computer that may be dangerous at times? The answer to this lies in a
very simple example. Consider a translator translating from English to
Japanese. The problem faced by the translator is that every language has its
own vocabulary and grammar. He may need to translate a word into a
sentence and destroy the beauty of the topic. And given that we do not know
img
ii
Japanese, so we cannot verify that our intent was correctly conveyed or not.
Compiler is such a translator, just a lot dumber, and having a scarce
number of words in its target language, it is bound to produce a lot of
garbage and unnecessary stuff as a result of its ignorance of our program
logic. In normal programs such garbage is acceptable and the ease of
programming overrides the loss in efficiency but there are a few situations
where this loss is unbearable.
Think about a four color picture scanned at 300 dots per inch making
90000 pixels per square inch. Now a processing on this picture requires
360000 operations per square inch, one operation for each color of each
pixel. A few extra instructions placed by the translator can cost hours of
extra time. The only way to optimize this is to do it directly in assembly
language. But this doesn't mean that the whole application has to be written
in assembly language, which is almost never the case. It's only the
performance critical part that is coded in assembly language to gain the few
extra cycles that matter at that point.
Consider an arch just like the ones in mosques. It cannot be made of big
stones alone as that would make the arch wildly jagged, not like the fine arch
we are used to see. The fine grains of cement are used to smooth it to the
desired level of perfection. This operation of smoothing is optimization. The
core structure is built in a higher level language with the big blocks it
provides and the corners that need optimization are smoothed with the fine
grain of assembly language which allows extreme control.
Another use of assembly language is in a class of time critical systems
called real time systems. Real time systems have time bound responses, with
an upper limit of time on certain operations. For such precise timing
requirement, we must keep the instructions in our total control. In higher
level languages we cannot even tell how many computer instructions were
actually used, but in assembly language we can have precise control over
them. Any reasonable sized application or a serious development effort has
nooks and corners where assembly language is needed. And at these corners
if there is no assembly language, there can be no optimization and when
there is no optimization, there is no beauty. Sometimes a useful application
becomes useless just because of the carelessness of not working on these
jagged corners.
The third major reason for learning assembly language and a major
objective for teaching it is to produce fine grained logic in programmers. Just
like big blocks cannot produce an arch, the big thick grained logic learnt in a
higher level language cannot produce the beauty and fineness assembly
language can deliver. Each and every grain of assembly language has a
meaning; nothing is presumed (e.g. div and mul for input and out put of
decimal number). You have to put together these grains, the minimum
number of them to produce the desired outcome. Just like a "for" loop in a
higher level language is a block construct and has a hundred things hidden
in it, but using the grains of assembly language we do a similar operation
with a number of grains but in the process understand the minute logic
hidden beside that simple "for" construct.
Assembly language cannot be learnt by reading a book or by attending a
course. It is a language that must be tasted and enjoyed. There is no other
way to learn it. You will need to try every example, observe and verify the
things you are told about it, and experiment a lot with the computer. Only
then you will know and become able to appreciate how powerful, versatile,
and simple this language is; the three properties that are hardly ever present
together.
Whether you program in C/C++ or Java, or in any programming paradigm
be it object oriented or declarative, everything has to boil down to the bits
and bytes of assembly language before the computer can even understand it.
ii
img
..
Table of Contents
Preface
i
Table of Contents
1 Introduction to Assembly Language
1
1.1.
Basic Computer Architecture
1
1.2.
Registers
3
1.3.
Instruction Groups
5
1.4.
Intel iapx88 Architecture
6
1.5.
History
6
1.6.
Register Architecture
7
1.7.
Our First Program
9
1.8.
Segmented Memory Model
12
2 Addressing Modes
17
2.1.
Data Declaration
17
2.2.
Direct Addressing
17
2.3.
Size Mismatch Errors
21
2.4.
Register Indirect Addressing
22
2.5.
Register + Offset Addressing
25
2.6.
Segment Association
25
2.7.
Address Wraparound
26
2.8.
Addressing Modes Summary
27
3 Branching
31
3.1.
Comparison and Conditions
31
3.2.
Conditional Jumps
33
3.3.
Unconditional Jump
36
3.4.
Relative Addressing
37
3.5.
Types of Jump
37
3.6.
Sorting Example
38
4 Bit Manipulations
43
4.1.
Multiplication Algorithm
43
4.2.
Shifting and Rotations
43
4.3.
Multiplication in Assembly Language
46
4.4.
Extended Operations
47
4.5.
Bitwise Logical Operations
50
4.6.
Masking Operations
51
5 Subroutines
55
5.1.
Program Flow
55
5.2.
Our First Subroutine
57
5.3.
Stack
59
5.4.
Saving and Restoring Registers
62
5.5.
Parameter Passing Through Stack
64
5.6.
Local Variables
67
6 Display Memory
71
img
iv
6.1.
ASCII Codes
71
6.2.
Display Memory Formation
72
6.3.
Hello World in Assembly Language
74
6.4.
Number Printing in Assembly
76
6.5.
Screen Location Calculation
79
7 String Instructions
83
7.1.
String Processing
83
7.2.
STOS Example ­ Clearing the Screen
85
7.3.
LODS Example ­ String Printing
86
7.4.
SCAS Example ­ String Length
87
7.5.
LES and LDS Example
89
7.6.
MOVS Example ­ Screen Scrolling
90
7.7.
CMPS Example ­ String Comparison
92
8 Software Interrupts
95
8.1. Interrupts
95
8.2. Hooking an Interrupt
98
8.3. BIOS and DOS Interrupts
99
9 Real Time Interrupts and Hardware Interfacing
105
9.1.
Hardware Interrupts
105
9.2.
I/O Ports
106
9.3.
Terminate and Stay Resident
111
9.4.
Programmable Interval Timer
114
9.5.
Parallel Port
116
10 Debug Interrupts
125
10.1. Debugger using single step interrupt
125
10.2. Debugger using breakpoint interrupt
128
11 Multitasking
131
11.1. Concepts of Multitasking
131
11.2. Elaborate Multitasking
133
11.3. Multitasking Kernel as TSR
135
12 Video Services
141
12.1. BIOS Video Services
141
12.2. DOS Video Services
144
13 Secondary Storage
147
13.1.
Physical Formation
147
13.2.
Storage Access Using BIOS
148
13.3.
Storage Access using DOS
153
13.4.
Device Drivers
158
14 Serial Port Programming
163
14.1. Introduction
163
14.2. Serial Communication
165
15 Protected Mode Programming
167
15.1.
Introduction
167
15.2.
32bit Programming
170
15.3.
VESA Linear Frame Buffer
172
15.4.
Interrupt Handling
174
16 Interfacing with High Level Languages
179
iv
img
TABLE OF CONTENTS
v
16.1. Calling Conventions
179
16.2. Calling C from Assembly
179
16.3. Calling Assembly from C
181
17 Comparison with Other Processors
183
17.1. Motorolla 68K Processors
183
17.2. Sun SPARC Processor
184
v