A Introduction To Pascal Inline Assembler
Index

Welcome to this beginners guide to Pascal inline assembler! This page is mainly written for those of youthat are familiar to pascal, but not to the inline assembler. Maybe you've read some of those pascalhelps there’s out there, and seen inline being frequently used, but didn't understand anything of it! Ormaybe you've figured a few things out about inline assembler, then see this as a way to master it! The first chapter will take up what assembler is and a little about the hexadecimal numeric format. Don't worry about this yet, you will understand it if you reed this tutorial. The next chapters will be aboutsome more usable options, but I haven't written them yet, so feel free to leave comments to me about what you don't understand and I’ll modify any unclearities. This tutorial won't take up every detailin the processor and explain what it does, I'll leave that bull to the bookwriters. I will mainlyexplain how to code it, and how to code it good! I guess you only read this because you want to optimize yourcode, so I'll teach you how you write the FAST assembler (FASTES is to much to say...). And of cource, thethings that you can't do in pascal is in here to. When you once start to use assembler for real, you'll learnthat it is the ONLY way to stay in total control of you program. But it fast gets messy, so remember to useblank lines and comments alot (that's ALOT, boys and girls!). To you programmers who already got the hungof the basics in assembler can go to the Advanced Section and the Graphics Section directly. ( Those arenot yet written, sorry). Those will discuss how to make your own graphics routines, mainly in mode 13 (320*200*256),and how to speed up your code with assembler.Well, the index:

INDEX

Chapter one : What is assembler?
Chapter two : The Basics

Back to MainPage


CHAPTER ONE
WHAT IS ASSEMBLER?

The processor in a 80X86 computer does not understand anything (surprise surprise), you must communicatewith it in it's own language. Now this happens to be in digits, and actually in only 1:s and 0:s, whichmakes it a pretty bad conversation partner. To tell it what you want it to do, you must translate yourcommands into numbers which means special operations. To memorize all the numbers the processor understandis fairly unsmooth, and look up every instruction in a codetable is pretty uncomfortable too. That's why wehave programming languages! Languages like Pascal and C++ and all other highlevel languages mainly readsa text file containing commands, and transferres it into machine language (the processors language) by it'sown rules. Every command in theese languages convertes into a bunch of processor commands. It is hard tooptimize the program for best performace. Now, the simplest programming language you could possibly think of is naturally one that only translates every command into a predefined number and your processor code is finished! That's assembler (almost). It's far more easy to understand than machine language, but puts you in total control.Since we shall only use inline assembler (so far), I will not tell you how to allocate variables or writing procedures in assembler, since BASM don't accept that. By the way, Borland Inline Assembler will from here on be referred to as BASM.

THE HEXADECIMAL NUMERIC FORMAT

You that know how the hexadecimal numeric format works can skip this part. There's nothing new. And ifyou have trouble understanding, it isn't that important, it just makes you get a better feeling with thenumbers.
As we all know, the normal numeric format is the one that goes 1,2,3,4,5,6,7,8,9,10,12,etc...That's the Decimal numeric system. It goes to nine, and then you get one extra digit in therow to the left. You say the decimal system has the base ten, because there is ten different digits. The Hexadecimal isn't that different. Only that it has the base sixteen, it goes to fifteen and then updatesthe digit to the left. To make this work you need new one-letter-digits for 10,11,12,13,14 and 15. This waseasily done by using the letters A,B,C,D,E and F. So in hexadecimal you count: 1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,10,11,etc...Study this table and try to understand.
DecimalHexDecimalHexDecimalHex
111610311F
2217113220
3318123321
4419133422
5520143523
6621153624
7722163725
8823173826
9924183927
10A25194028
11B261A4129
12C271B422A
13D281C432B
14E291D442C
15F301E452D

To convert a decimal number into hexadecimal, you will have to do a series of divisions. You first divide by a number in the series 16,256,4096,65536,etc...(16^x) the highest you can use. The result is the first digit from the rigth. Then youdivide the remainder by the next (lower) number in the serie and you get next number and so on. An example:
You have the number 123457 decimal and want it in decimal. Then you first divide by 65536 and get 1. That's thefirst digit. Then you divide the remainder (57921) with the next number, 4096, and get 14. That is E in Hex, and wehave the second digit. Then we continue by dividing the remainder (577) by 256 and get 2, third figure, and divideremainder 64 by 16 and get 4. The remainder now is 1, and thats the last digit. What we got was 1E241. You canconvert the other way by taking the last digit plus the second from right times 16 plus next times 256 and so on...
All this ain't that important, but if you wish to understand everything good you better learn this plus thebinary numeric format. You can probably get better explanations on theese topics somewhere out there...One more thing, when I use any hexadecimal number it will either be prefixed by a "$" or followed by "h", just asyou can do in Borland Pascal.



CHAPTER TWO
THE BASICS

The processor uses the memory for most operations, like most operations in pascal do. That's the manipulating ofvariables we all are so used to! But updating the memory all the time takes time. By using the processors own "memory" we speed things up. The processor has four "varibles" to use; the registers. There's more thanthat, but we begin here. Since BP still don't support 32bit assembler code, the registers are 16bit, meaning they can take a value between 0 and 65535 (a word). The four registers is called AX,BX,CX and DX. That seems logical but it actually means something! AX is the Accumulator. You use it when you multiply or divide, but you can use it only to store numbers in to, which is what we will begin with. The BX is the Base register,it is used to everything, it have a advanced function but you never use it... CX is the Counter register.To do loops (for-like stuff) you use it to count down. Finaly DX is the Data register. It is used for temporary memory movement, like the remainder after a division. All theese registers is 16 bit. You canaddress the upper 8 bit by typing AH,BH,CH & DH and the lower by AL,BL,CL & DL (H for high and L for low).And if BASM had supported 32 bit the you would have reffered the whole registers as EAX,EBX,ECX and EDX but now you will never do that... Of course you can refer to them all in small letters. Another importand thingis to remember that you don't won't to use real type variables with assembler. You can do it, but it unessecary and slow. You might have noticed that using decimal variables slows down your pascalprogramalot. In this tutorial I will teach you how to use fixpoint to use decimals fast.

The BASM in pascal is used by typing first ASM and then writingthe code. If you use BP 7.0 you will notice the text going green. You end the assembler code part by typingEND;So if you write a assembler part itcould look like:
asm





end
;
mov
int
push
pop
mov

AX,$13
$10
$A000
ES
AX,43
As you see you usaly have one command per line. Most commands are two, three or four letters. They usalyhave a number of attributes, typed after the command and separated by colons(,).You can write semicolonsafter each row, but it's not neccesary. What this little program do you will understand soon.

Now we are ready for the first commands. In assembler the command mov is probably the most used. What it does is it moves something from one location to another. Actually it copies it, leaving the sorce unmodefied. The syntax is: mov destination,source.The value in source copys to destination (e.g. mov var,255 moves the value 255 into the variable var).If you want the value in a variable to be put in the AX register, you should type:mov ax,variable.There is a few things to look up for though. You can't move one variable to another, you must pass it to a register first. And you can't writemov 134,ax.That would try to put the value in ax in the value 134, and where whould that be?
Two other often used commands are add and sub. They add and subtracts. the suntaxes are:add destination,source andsub destination,source.What they do is takes the destination and adds/subtracts the source and puts the result in destination. You can'thave a number (an immediate value) as destination. To subtract 97 from 213 we could type:
mov ax,213
sub ax,97
.
We first put the original valuein ax and then subracts it with 97. Make sure you understand this, because it's essential!

In the beginning, there was but a few commands... The four most basic commands there is is AND, OR, XOR andNOT. They are the simplest commands a processor can do, and they are as fast as it can be. Theese operations are thewery stone on wich all electonics was built. When the first "electronic calculator" was build, this was what itcould do. To fully understand what they do you must fully understand the binary numeric format. If you know what theydo the syntax is as follows:
and destination,source
or destination,source
xor destination,source
not destination
The only thing you others need to know right now (we'll get back to theese in the advanced speedup sections) isthat writing xor ax,ax puts ax to zero VERY fast. Of course it workswith all registers.
Some other basic commands are mul anddiv. They multiply and divide. The syntax is
mul source
div source
They multiply/divide AX with the source and puts the answer in AX. If the result of an multiplication is to big,the higher 16 bit is in DX. Also, if there is a remainder it is put in DX. So make sure you don't have any important value in DX, because it otherwise it will be lost (if there is no higher bits or remainder,DX is set to zero). Now, lets explain by a example! Say you have a value in the variable tal and another in the variable tal2 and wish to dividethem. The result is to be put in the variable resultand the remainder in the variable remind. That could look like this:
asm
mov ax,tal
div tal2
mov result,ax
mov remind,dx
end;
{ puts the value in tal into AX }
{ divides the value in AX by tal2 }
{ the result was put in AX, and is now moved to result }
{ the reminder was in DX and is now moved to remind }
This pascal source does the same thing as the assembler do, but the assembler is faster.
result:=tal div tal2;
remind:=tal
mod tel2;

ProcedurePutPixel(xpos,ypos:word;color:byte);Assembler;
Asm

mov ax,ypos
mov bx,xpos
xchg ah,al
add bx,ax
shr ax,2
add bx,ax
push $a000
pop es
mov dl,color
mov es:[bx],dl

End;

Back to Main Page


Leave your comments to Joke_dST@Geocities.com
1