We have always found OP (Object Pascal) to produce fast and more
efficient code, add this to the RAD Environment of Delphi and Kylix
and the need to use assembler becomes questionable.
This article is somewhat of an extract from the excellent paper
"Learning Assembler with Delphi" from Ian Hodger at:
http://www.delphi3000.com/articles/article_2245.asp
It was the wish of my students to shorten it and say a few words about
debugging.
Attached to this newsletter you'll find an impressive assembler example
in a DOS-Shell, it's shows a graphic-fire on the screen.
In all of our work with OP, we faced just five situations where we have
felt one should consider the use of low level system code:
1. Stepping & processing large quantities of data. Of course I exclude
from this any situation where a data query language with a query
optimizer is employed, but not always in an automation- or micro-
controller environment.
2. For scientific reasons to provide high speed simulations or just for
education with Compiler-Assembler-Linker-Loader steps. I call that
CALL.
3. For controller programming or to develop or test peripherals like
COM-devices, e.g. on how to detect free COM ports (as far as Windows
knows...) and call some functions Windows doesn't allow, i.e. does
not detect a COM port if a mouse is attached. Uses a DPMI call with
assembler.
4. High speed display routines; here we want quick and easy routines
that comes with OP, not the strange C++ headers, external function
libraries or confused hardware demands of DirectX.
5. Strong and fast encryption algorithms like ciphers, hashes or
checksums, so the core encoding and decoding routines are written in
highly optimized assembler code.
To say that writing machine code is cosy would be an understatement and
as for debugging an assembler language is just an easy way of
remembering what machine code operations are available. The job of
converting to machine code is done by an assembler, so Borland's Turbo
Assembler is built into Delphi.
Let's practice a little "Bit":
If we look at adding an integer 15 to the register eax, the appropriate
assembler instruction is
add eax,15 // a := a + 15
Almost the same, to subtract the value of ebx from eax
sub eax,ebx // a := a - b
To save a value for a happy day, we can move it to another register
mov eax,ecx // a := c
or even better, save the value to a memory address
mov [1733],eax // store value of eax at address 1733
and of course to retrieve it with
mov eax,[1733]
This means also the the largest number we can store in a register, e.g.
eax is 2 to the power 32 minus 1, or exactly 4294967295.
Bear in mind the size of the values you are moving about; the mov
[1733],eax instruction affects not only memory address 1733, but 1734,
1735 and 1736 as well, because as you will recall eax is 32 bits long,
or rather 4 bytes, therefore memory is always addressed in bytes!
Next step is the example:
step := step + 1;
we would write something like this:
mov eax, step
add eax, 1
mov step, eax
or simply:
inc step
Now we're ready for our first snippet of assembler, but let aside the
simple nature of this example. Consider the following lines of OP code:
function BigSum(A, B: integer): integer;
begin
result := A+B;
end;
OP provides the asm...end block as a method of introducing just plain
assembler to our code. So we could rewrite the function BigSum as:
function BigSum(A, B: integer): integer;
begin
asm
mov eax,A
add eax,B
mov result,eax
end;
end;
This works fine, but there is a point to consider. There is no speed
gain and we've lost the readability of our code. But the fact is, all
our sophisticated class design is "broken" by an assembler.
You can also write complete procedures and functions using inline
assembler code, without including a begin...end statement, e.g.:
function LongMul(X, Y: Integer): Longint;
asm
mov eax, X
imul Y
end;
The compiler performs several optimizations on these routines so no
code is generated to copy value parameters into local variables. This
affects all string-type value parameters and other value parameters
whose size isn't 1, 2, or 4 bytes. Within the routine, such parameters
must be treated as if they were var parameters.
If we are going to produce really useful code, at some point we shall
need to implement more deeper routines. E.G. we have to display the
output of some function dependent 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 imagination of depth. This can be achieved by using colors of
differing intensity, 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.
Debugging code
To finish this article, let's say few words about debugging. It is very
easy to set up watches, program breaks, and traverse OP programs a line
at a time. The same is true, even when using assembler. All we need to
do is add the four 32bit general registers eax, ebx, ecx and edx to
one's watch list, and see the effect of each line of assembler. In a
DOS-Shell you can also type "debug" and then "u" for disassembly. The
built-in assembler allows you to write Intel assembler code within OP
programs. It implements a large subset of the syntax supported by Turbo
Assembler and Microsoft's Macro Assembler, including all 8086/8087 and
80386/80387 opcodes and all but a few of Turbo Assembler's expression
operators.
Assembler functions return their results as follows:
- Ordinal values are returned in AL (8-bit values)
- AX (16-bit values), or EAX (32-bit values)
- Real values are returned in ST(0) on the coprocessor's register stack
- Pointers, including long strings, are returned in EAX
- Short strings and all the variants are returned in the temp. location
pointed to by @result
So I hope you feel a little "Bit" the speed of Delphi and thanks Ian for
his fundamentals.
5. TTRAYCOMPONENT
Stewart Moss presents his modification
of TrayComponent to make the "Show in Taskbar" code work under Windows
2000/NT. TrayComponent was originally written by Alexander Rodigin,
based on the Stealth component by Janus N. Tøndering and the TrayIcon
component by Pete Ness. The component is in the file TrayComp.pas.
________________________________________________________________________
6. STOP WINDOWS FROM DISPLAYING CRITICAL ERROR MESSAGES
By Zarko Gajic http://delphi.about.com
When performing certain functions it is necessary for your program to
take full control over error messages. For example, if your program
wants to "quietly" check if a floppy drive has a floppy disk in it, you
may not want Windows to display a "critical error" if in fact the
floppy drive is empty.
You can control which error messages Windows displays by using the
"SetErrorMode()" Win API function as follows:
var
wOldErrorMode: Word;
begin
// tell windows to ignore critical
// errors and save current error mode
wOldErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS);
try
// code that might generate a critical error goes here...
finally
// go back to previous error mode
SetErrorMode(wOldErrorMode);
end;
end;
7. SHOWING WINDOWS "OPEN FOLDER" DIALOG (II)
In the last issue I published source code to show the standard Open
Folder dialog, and since I received a lot of feedback about it, I
thought the article deserved a second part addressing a few issues
raised by the readers.
SelectDirectory
Many people reminded me that the SelectDirectory function that comes in
the FileCtrl unit does that. Well, actually, this is not correct...
One of the two overloaded versions of SelectDirectory allows you to set
the root path, but not the selected directory:
var
Directory: string;
begin
Directory := 'C:\Delphi\';
if SelectDirectory('Select folder', '', Directory) then
ShowMessage(Directory);
end;
The other version of SelectDirectory allows you to set the selected
directory, but not the root directory, although it has some interesting
features (you can allow directory creation, the user can type the
directory name, and you can provide a context help id), but this
version of the function doesn't use the standard Windows' "Open Folder"
dialog:
var
Directory: string;
Begin
Directory := 'C:\Delphi\';
if SelectDirectory(Directory, [], 0) then
ShowMessage(Directory);
end;
Disposing PIDLs
In the code I used GlobalFreePtr to deallocate the memory allocated for
a PIDL. It's a quick and dirty way to do it but unsafe. PIDLs should be
released by calling IMalloc.Free. An easy way to replace GlobalFreePtr
could be using the following function:
uses shlobj, ActiveX;
procedure IMallocFree(Ptr: Pointer);
var
pMalloc: IMalloc;
begin
if Succeeded(SHGetMalloc(pMalloc)) then
pMalloc.Free(Ptr);
end;
Root directory as string
A couple of readers requested that instead of the CSIDL of a special
folder the root parameter could be any directory passed as a string, so
I made a few changes in the source code to get the corresponding value
for TBrowseInfo.pidlRoot based on the root parameter (now called
RootFolder, a WideString):
:
function BrowseForFolder(Title: string; RootFolder: WideString = '';
InitialFolder: String = ''): string;
var
:
IDesktopFolder: IShellFolder;
Eaten, Attributes: LongWord;
begin
with BrowseInfo do begin
:
pidlRoot := nil;
if RootFolder <> '' then begin
SHGetDesktopFolder(IDesktopFolder);
IDesktopFolder.ParseDisplayName(Application.Handle, nil,
PWideChar(RootFolder), Eaten, pidlRoot, Attributes);
end;
:
end;
:
end;
8. FORUMS
Delphi
If you know much of Delphi but you are still far from being a guru this
forum is for you. This is the only forum for intermediate-level Delphi
programmers on the Web (Delphi hackers are also welcome :-)). The forum
now has more than 610 members and last February it had a nice level of
traffic with almost 250 messages:
http://groups.yahoo.com/group/delphi-en
If you want to join the group, the best way is to subscribe from the
web since you can access the special features available at the web site
(a Yahoo! ID is required and you can get yours free by registering as a
Yahoo! user), but if you don't want to register or if you don't have
full Internet access you also can subscribe by email:
http://groups.yahoo.com/group/delphi-en/join
delphi-en-subscribe@yahoogroups.com
Components
This is a forum for searching/recommending software components (VCL and
CLX components, ActiveX objects, DLL libraries, shared objects, etc.),
as well as utilities, tutorials, information, etc. The forum is rather
new and currently counts with a little over 125 members and very low
traffic:
http://groups.yahoo.com/group/components
I hope you join the forum to help us build a larger group. You can
subscribe from the web or --more easily-- by email:
http://groups.yahoo.com/group/components/join
components-subscribe@yahoogroups.com
________________________________________________________________________
9. DELPHI ON THE NET
By Dave Murray
Components, Libraries and Utilities
Shareware/Commercial
* Database Pro v1.14 - by IMG Software
Database Pro includes eleven components and give the most simple and
fast way to filter or find values in the database. You will get:
1) The simplest way to assign conditions of filtering / data retrieval
2) Support BDE, MIDAS, ADO, InterBase, KADao and any alternative
Database Pro is currently available in 18 languages.
http://www.imgsoft.com
* RichView Package - by TRICHVIEW.COM. Shareware ($139)
RichView is a suite of native Delphi/C Builder components for editing
formatted documents with images, tables and hypertext links.
Customizable attributes of text and paragraphs, Unicode, bi-directed
text, HTML export, RTF, printing, data-aware versions and more...
http://www.trichview.com/
* SMImport Suite v1.46 - by Scalabium, Mike Shkolnik
SMImport suite is a components for data loading from Text, CSV, HTML,
XML, MS Excel (without OLE), MS Access, Lotus 1-2-3, QuattroPro and
Paradox/DBF. Available for Delphi 3-6 and CBuilder 3-6, price: $35.
http://www.scalabium.com (mshkolnik@scalabium.com)
Freeware
* dbExpress InterBase 6.5 driver for Delphi 6 available - by J Kaster
http://community.borland.com/article/0,1410,28508,00.html
Articles, Tips and Tricks
* Bring RAD to your Web app development with WebSnap - by GetPublished
WebSnap enables Delphi to build the scriptable business objects,
database driven web pages, and back-end servers that are integral to
a successful, dynamic web site.
http://community.borland.com/article/0,1410,28567,00.html
* Simple scripting with NetCLX extension components - by John Kaster
C++ Builder 6, Delphi 6 and Kylix all have new RTTI functions that
make simple scripting much easier to implement. John K shares some
producer components that show how.
http://community.borland.com/article/0,1410,28551,00.html
* From XML to Object: Part II - by Keith Wood
Wraps up this series on the XML Data Binding Wizard with sample
applications that demonstrate how to read and display XML documents
and generate new ones.
www.delphimag.com/features/2002/04/di200204kw_f/di200204kw_f.asp
* A Smart Combo Box, etc - by Bruno Sonnino
How to create a combo box that remembers the user's selection or
entry, and offers it as the default the next time around and tips for
RadioGroups and What's This? help.
www.delphimag.com/features/2002/04/di200204bs_f/di200204bs_f.asp
* Taming the Beast from Redmond - by Dave Ball
A step-by-step explanation of how to deploy ISAPI DLLs within an MTS
or COM+ memory-protected development environment, by configuring IIS
settings within the MMC.
www.delphimag.com/features/2002/04/di200204db_f/di200204db_f.asp
* Take Action - by Bill Todd
If you want your menus and toolbars to have the look and feel of
Office 2000, the ActionManager and ActionBars in Delphi 6 may be just
the ticket.
www.delphimag.com/features/2002/04/di200204bt_f/di200204bt_f.asp
* How to get an MP3's ID3-Tag?
http://www.swissdelphicenter.ch/en/showcode.php?id=121
* How to load Rft Text from a resource file into a TRichEdit?
http://www.swissdelphicenter.ch/en/showcode.php?id=1049
* How to refresh the icon cache?
http://www.swissdelphicenter.ch/en/showcode.php?id=1054
* How to enable the Return key in a TWebbrowser?
http://www.swissdelphicenter.ch/en/showcode.php?id=1055
* How to open local files in a TWebbrowser and start links directly?
http://www.swissdelphicenter.ch/en/showcode.php?id=1057
* How to program a peak level meter? - by Steve Schafer
http://www.swissdelphicenter.ch/torry/showcode.php?id=1086
* How to show the source code of a webpage in a Memo? - by Screaminator
http://www.swissdelphicenter.ch/torry/showcode.php?id=1085
* How to perform a binary seach on a TListview? - by P Below
http://www.swissdelphicenter.ch/torry/showcode.php?id=1078
* Add current page of a TWebbrowser to your favorites - by Screaminator
http://www.swissdelphicenter.ch/torry/showcode.php?id=1094
* How to connect to an ftp server + download a file? - by Thomas Stutz
http://www.swissdelphicenter.ch/torry/showcode.php?id=1095
* How to check if a given folder is empty - by Christian Cristofori
http://www.delphi3000.com/articles/article_3095.asp
* Component for saving User Settings (using Tools API) - D Wischnewski
Writing a Component, a Component Editor and a Property Editors.
http://www.delphi3000.com/articles/article_3096.asp
* A Simple Notepad with Delphi 6 - by S S B Magesh Puvananthiran
http://www.delphi3000.com/articles/article_3098.asp
* Implementation of the State Design Pattern - by Jochen Fromm
http://www.delphi3000.com/articles/article_3099.asp
* Find full path of registered Applications - by Andreas Schmidt
http://www.delphi3000.com/articles/article_3101.asp
* Exporting Syntax Highlighted text to HTML - by Danilo Vieira
http://www.delphi3000.com/articles/article_3103.asp
* Converting HTML colour names and codes to TColor - by D Wischnewski
http://www.delphi3000.com/articles/article_3104.asp
* Writing all controls of given component to TXMLDocument - by N Ozniev
http://www.delphi3000.com/articles/article_3106.asp
* Sending email in console mode - by Arman Rad
http://www.delphi3000.com/articles/article_3107.asp
* Creating High Performance Middleware Apps with Indy - by Romeo Lefter
Indy Step by Step part 4.
http://www.delphi3000.com/articles/article_3108.asp
* Move or resize a TControl object graphically - by Bertrand Goetzmann
Graphically move or resize a TControl object by using another object
that has all the necessary code.
http://www.delphi3000.com/articles/article_3109.asp
* How to get the long path and file name? - by Maarten de Haan
How to get the long path and file name from a DOS name.
http://www.delphi3000.com/articles/article_3110.asp
* Viewing Targa Bitmap File Format in Delphi (256-colors) - by h4ry p
http://www.delphi3000.com/articles/article_3113.asp
* Easiest way to draw a transparent image - by h4ry p
http://www.delphi3000.com/articles/article_3115.asp
* Un-hiding Properties - by Romeo Lefter
Unhiding some usefull properties for VCL controls.
http://www.delphi3000.com/articles/article_3116.asp
* PAS 2 HTML converter - by Eber Irigoyen
Sourcecode to HTML converter for web pages with highlighted syntax.
http://www.delphi3000.com/articles/article_3117.asp
* Grab the PC Serial Number & BIOS info using WMI calls - by Doug Good
Windows Management Instrumentation Calls in Delphi.
http://www.delphi3000.com/articles/article_3118.asp
* Windows detection routines - by Ronald Buster
Here is how to find out the Windows versions for all versions.
http://www.delphi3000.com/articles/article_3119.asp
* Easy logger - by Eber Irigoyen
http://www.delphi3000.com/articles/article_3121.asp
* Placing icons in DBGrid - by Fahad Aljarbou
http://www.delphi3000.com/articles/article_3122.asp
* Extract Icons from .exe, .dll, .lnk - by Prashant Gulati
http://www.delphi3000.com/articles/article_3126.asp
* Syntax Highlighted Source Code Export to HTML or RTF - by Jim McKeeth
Export many different source code files into HTML or FTP with Syntax
Highlighting and end user customization
http://www.delphi3000.com/articles/article_3128.asp
* Web Page to Image File - by Jim McKeeth
How to get the URL from IE, open it with PBear's THTMLViewer and save
it as a image file.
http://www.delphi3000.com/articles/article_3129.asp
* A simple class to implement compound files - by David Bolton
How do I store multiple files within one compound file?
http://www.delphi3000.com/articles/article_3130.asp
* Improving your Object classes reliability - by David Bolton
How to reference count the easy way.
http://www.delphi3000.com/articles/article_3132.asp
* How to send HTML messages with attachments (using Indy) - by N Cross
Using IdMessage to send HTML formatted emails with attachments.
http://www.delphi3000.com/articles/article_3133.asp
* How to parse a wave file? - by Liran Shahar
Parsing a wave file to access each of its chunks.
http://www.delphi3000.com/articles/article_3134.asp
* SignalDisplay component - by Liran Shahar
Ever wanted to display audio from a microphone or see wave file
samples like CoolEdit does?
http://www.delphi3000.com/articles/article_3135.asp
* How to get keys, like up,down,left, right? - by Etienne Nijboer
http://www.delphi3000.com/articles/article_3136.asp
* Determine If a File has One of Several File Extensions - by John Long
http://www.delphi3000.com/articles/article_3137.asp
* Changing IE Proxy Settings - by Shannon Wynter
How do I set proxy settings in IE without having to restart?
http://www.delphi3000.com/articles/article_3138.asp
* How do we implement the Choice Pattern - by Max Kleiner
Working with Interfaces.
http://www.delphi3000.com/articles/article_3141.asp
* How to make a Window with RAW API - by Simone Di Cicco
http://www.delphi3000.com/articles/article_3142.asp
* From XML to Object: Part I - by Keith Wood
The Delphi 6 XML Data Binding Wizard.
www.delphimag.com/features/2002/03/di200203kw_f/di200203kw_f.asp
* Differential Equations - by Alexander Gofen
Implement the Taylor center, a powerful numeric and expression-
processing application with extensive visual features, in Delphi.
www.delphimag.com/features/2002/03/di200203ag_f/di200203ag_f.asp
* Hot Spots: Part II - by Victor Hornback
Build a custom component, showing how to register a custom property
editor, stream non-published data, and more.
www.delphimag.com/features/2002/03/di200203vh_f/di200203vh_f.asp
* Spreadsheet Data via ADO, ODBC, or Automation - by Bill Todd
A detailed explanation and example projects for accessing MS Excel
spreadsheet data via ADO, ODBC, or automation.
www.delphimag.com/features/2002/03/di200203bt_f/di200203bt_f.asp
* Bug in StringReplace (Handling Null characters) - by Stewart Moss
Workaround for a bug in StringReplace function when used on a string
which contains NULL (#0) characters (not null terminated).
http://www.delphi3000.com/articles/article_3090.asp
* Making a "recent files" menu - by Dan Strandberg
How to make a simple "recent files" menu/list in your application.
http://www.delphi3000.com/articles/article_3091.asp
* Yet another "recent file" menu - by Magnus Flysjö
http://www.delphi3000.com/articles/article_3093.asp
* RGB and HSV conversions - by William Egge
Explains HSV and RGB colour values and includes source for converting
between the two.
http://www.delphi3000.com/articles/article_3094.asp
* Quiz: Delphi ADO Programming - by Zarko Gajic
Who Wants to be a Delphi ADO Database Programming Guru - trivia game.
One copy of a great Delphi book will be given away in this
"competition". Closing date is 31st May and a winner will be picked
randomly on 1st June.
http://delphi.about.com/library/weekly/aa030502a.htm
* Spell Checking with MS Word - by Zarko Gajic
Why buy or write spell checking components when you can use MS Word?
Add spell checking + thesaurus capabilities to your Delphi app using
the MS Word Object Library.
http://delphi.about.com/library/weekly/aa032701a.htm
* Creating PDF Documents, the free way - by Romeo Lefter
How to create easy and fast PDF Documents.
http://www.delphi3000.com/articles/article_3076.asp
* Implementation of the Memento Design Pattern - by Jochen Fromm
How do you implement the MEMENTO Design Pattern in Delphi ? A Memento
is an object that stores a snapshot of the internal state of another
object - the memento's originator.
http://www.delphi3000.com/articles/article_3077.asp
* Reducing Source Code Complexity in your application - William Egge
Using a MessageCenter to link your application systems together.
Implementation of an observer pattern except that it uses Delphi's
built in message dispatching and also maintains the relationships.
http://www.delphi3000.com/articles/article_3079.asp
* Creating a simple HTTP Server
How to create a simple HTTP server using TIdHTTPServer from Indy
and the TPageProducer for simple scripting capabilities.
http://www.delphi3000.com/articles/article_3081.asp
* Read/write summary information of an Office document - by B Goetzmann
How read/write summary information of an Office document?
http://www.delphi3000.com/articles/article_3082.asp
* How to create disabled bitmap - by Mike Shkolnik
How can I create a disabled bitmap from original?
http://www.delphi3000.com/articles/article_3085.asp
* Convert Tab to Space - Yilmaz Kaygisiz
How Can i Change TAB Char To Space in my string?
http://www.delphi3000.com/articles/article_3086.asp
* String or Number? Undocumented Effects of Val(...) - by D Wischnewski
Interesting phenomenon where obvious string is incorrectly converted
into a number by Delphi functions Val, IntToStr + InToStrDef.
http://www.delphi3000.com/articles/article_3087.asp
* Lost your MainForm? - by Eber Irigoyen
Has it ever happened to you that the MainForm that you want is not
listed in Delphi's Projects|Options|General?
http://www.delphi3000.com/articles/article_3088.asp
Kylix
* Simple scripting with NetCLX extension components - by John Kaster
C++ Builder 6, Delphi 6 and Kylix all have new RTTI functions that
make simple scripting much easier to implement. John K shares some
producer components that show how.
http://community.borland.com/article/0,1410,28551,00.html
* How to catch kernel-signals in Kylix?
http://www.swissdelphicenter.ch/en/showcode.php?id=1059
* How to use RCDATA resources in Kylix?
http://www.swissdelphicenter.ch/en/showcode.php?id=1060
* How to clone a process in Linux?
http://www.swissdelphicenter.ch/en/showcode.php?id=1061
Tutorials
* Cup of Coffee for Dolphins Part I - by John Kaster
Java for Delphi programmers. Describes basic Java instructions in
comparison with Delphi.
http://community.borland.com/article/0,1410,28481,00.html
YOU CAN HELP US
We need your help to keep this newsletter going and growing. You can
help by referring the newsletter to your colleagues:
http://www.latiumsoftware.com/en/pascal/delphi-newsletter.php
Or you can help by voting for us in some or all of these rankings to
give more visibility to our web site and thus increase the number of
subscriptions to this newsletter:
http://www.programmingpages.com/?r=latiumsoftwarecomenpascal
http://top100borland.com/in.php?who=20
It's just a few seconds for you that REALLY mean a lot to us.
If you haven't received the full source code examples for this issue,
you can get them from http://www.latiumsoftware.com/download/p0034.zip
This newsletter is provided "AS IS" without warranty of any kind. Its
use implies the acceptance of our licensing terms and disclaimer of
warranty you can read at http://www.latiumsoftware.com/en/legal.php
where you will also find a note about legal trademarks. Articles are
copyright of their respective authors and they are reproduced here with
their permission. You can redistribute this newsletter as long as you do
it in full (including copyright notices), without changes, and gratis.
Group home page: http://groups.yahoo.com/group/pascal-newsletter/
Subscribe/join: pascal-newsletter-subscribe@yahoogroups.com
Unsubscribe/leave: pascal-newsletter-unsubscribe@yahoogroups.com
Report spam/abuse: abuse@yahoogroups.com
Need help with your subscription? eds2008 @ latiumsoftware.com
Latium Software http://www.latiumsoftware.com/en/index.php
Copyright (c) 2002 by Ernesto De Spirito. All rights reserved.
|
|