| RTL reference|Glossary|Tips/Tricks|FREE App/VCL|Best'O'Net|Books|Link To |
| Learning Assembler with Delphi | |||||||||||||||||||||
| Page 3: A proper example - using asm instructions. | |||||||||||||||||||||
A proper example Suppose we have to display the output of some function dependant upon two variables. You might imagine this as a three-dimensional map, where the coordinates [x,y] correspond to a height h. When we plot the point [x,y] on the screen we need to give the impression of depth. This can be achieved by using colours of differing intensity, in our example, blue below sea level and green above. What is needed is a function that will convert a given height into the appropriate depth of color for a given sea level.
First we should plan the ranges of the variables involved. It is reasonable to use the integer type to store the height and sea level, given the range of a 32-bit value. The true colour range available, limits us to a maximum color depth for blue and green to 256, so we will have to scale the results accordingly. If we assume a maximum height above, and depth below sea level to be 65536 feet, we can use shl and shr for some fast scaling, and we will get a change in colour depth every 256 feet. The function will of course, have to return a TColor type to be compatible with Delphi.
As it happens, the above routine can be written with Delphi's assembler directive. This method of writing assembler removes a lot of the protection provided by the complier, but as compensation, speed improves.
Here is the above routine using the assembler directive.
At first sight it is a little difficult to see what's going on. The registers are set with certain values before entering the function or procedure. How these are set depends on how the function or procedure was defined. There are two possibilities.
Stand alone, or explicitly defined procedures and functions On exit,
eax holds the result of the function, or in the case of a procedure, convention states it holds the value of any relevant error code you may define. Object method, procedures and functions On exit, the register values are as for a stand alone procedure or function.
With the above information, you should now be able to work your way through the ColorMap function. On the face of it, we seem to have reduced the number of lines of assembler from 18 to 15, which is not much of a saving, and the code is not as readable. However this is not the whole story. The complier generates a fail-safe entry and exit code block for any function or procedure defined with the usual begin..end block. By using the assembler directive, the complier employs only minimal entry and exit code. In the case of the ColorMap function this means it's code size has roughly halved, as has its execution time. These are the levels of performance gain that make writing assembler worthwhile.
Implementing local variables Local constants, and constant variables may also be defined just as one would in Object Pascal. The complier just reserves a block of memory, whose address is stored in ebx on entry. Thereafter the local variable names refer to an offset value from the base address of the data block. This allows the complier to use the index addressing provided by the cpu. An index address is of the form [reg1+reg2] or [reg1+exp1] for example [ebx+edx] . You will find indexing the easiest way of addressing data such as strings and arrays but more of this later. In the case of a function definition, a reference to a local variable is implemented as an indexed address irrespective of the operation, consequently the operation mov eax,second is actually mov eax,[ebx+4] where 4 is the offset to the address of the value of the second variable. You could write either, but the former offers greater clarity. I hope you are now starting to appreciate the importance of maintaining the value of ebx.
There is also a quicker method of temporary value storage, and this brings us to the stack.
The Stack push reg1 place the value of reg1 on top of the stack.
pop reg1 remove the top value of the stack, and place this in reg1.
Windows uses the stack to pass parameters to the api functions, and as such great care must be exercised when using the stack. Each push must have an associated pop in all the code you write, get this wrong and once again the system will crash.
We will use the stack, indeed it is necessary when implementing recursive functions, but generally we shall only use the stack for temporary storage. For example when using the mul and div operations there are register value changes all over the place,
An aside on recursion. Avoid it at all costs. Recursive functions may look elegant and appear to use very little code to achieve a great deal, but they are the signature of the inexperienced. A recursive function will commonly overload the stack because at design time you cannot be certain how many recursions are required and as such the memory demands are unknown. How do you explain to an end-user that your 100K program requires 8mb to run, when an equivalent iterative routine may produce a 500K program needing just 1mb. Furthermore, discovering the cause of a stack failure is problematic, making debugging a painful process. The only time I can think of, where recursion is justified, is in the implementation of artificial intelligence algorithms. It might also be noted that generally, I have found iteration to be quicker.
Beyond integers What's in a pointer |
|||||||||||||||||||||
All graphics (if any) in this feature created by Zarko Gajic.
| More Delphi |
|
· Learn another routine every day - RTL Quick Reference. · Download free source code applications and components. · Talk about Delphi Programming, real time. · Link to the Delphi Programming site from your Web pages. · Tutorials, articles, tech. tips by date: 2001|2000|1999|1998 or by TOPIC. |
|
· NEXT ARTICLE:
Searching for data - DB/9. Chapter nine of the free Delphi Database Course for beginners. Walking through various methods of data seeking and locating while developing ADO based Delphi database applications. |
| Stay informed with all new and interesting things about Delphi (for free). |
|
|
| Got some code to share? Got a question? Need some help? |

