News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Somewhat confused on Inc infrastructure!

Started by Chip, July 05, 2006, 07:13:39 AM

Previous topic - Next topic

Chip

Below are three sets of code; Programmers Reference, Sample code and the code I wish to implement.

Perhaps being from an older school, I am more comfortable with self-documenting programs.  The use
of the Inc file seems to preclude this.  Is there a way to determine the correct structure for use, and then
cut and paste the whole thing into my Asm code?  (Even if all elements are not used, they can always
be deleted later in an optimizing exercise.) 

I seem not to have grasped exactly where major structures are located, since so many (File use, etc.)
elements are grouped together.  Also, my impression is that many constants are coded in the Inc files
as individual elements rather than as part of a structure.

Thanks

Chip

Sample Code follows:


***************************  Found in Programmer's Reference ************************
HANDLE CreateFile(
  LPCTSTR lpFileName,
  DWORD dwDesiredAccess,
  DWORD dwShareMode,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  DWORD dwCreationDisposition,
  DWORD dwFlagsAndAttributes,
  HANDLE hTemplateFile
);

***************************  Found in other source code       ************************

;Open the file
   push   0         ;hTemplateFile
   push   FILE_ATTRIBUTE_NORMAL   ;dwFlagsAndAttributes
   push   OPEN_EXISTING      ;dwCreationDisposition
   push   0         ;lpSecurityAttributes
   push   FILE_SHARE_READ      ;dwShareMode
   push   GENERIC_READ      ;dwDesiredAccessADDR szFileTemp
   push   ADDR szFileTemp      ;lpFileName
   call   [CreateFile]      ;Kernel32

   cmp   eax,INVALID_HANDLE_VALUE
   je   >.Error

   mov   [hFile],eax


***************************  WHAT I would like to code       ************************

Invoke CreateFile,  0,                                \
               FILE_ATTRIBUTE_NORMAL,      \   
               OPEN_EXISTING,            \
               0,                      \
               FILE_SHARE_READ               \
               GENERIC_READ,            \
               ADDR szFileTemp
               
               cmp   eax,INVALID_HANDLE_VALUE
               je   >.Error
               mov   [hFile],eax


I am on Skype under my email address!

jorgon

Chip

QuotePerhaps being from an older school, I am more comfortable with self-documenting programs.

I would tend to agree with this comment.  Except in complex source code, I would prefer to be able to understand the source code from one document rather than having to look at an include file (or a list of macros for that matter) to see what is really going on.

I think your plan to start by looking at the programmer's reference is a good one, since if you want to call a particular API with which you are not acquainted, this will be your natural starting point.

So in my answer here I analyse how you can create comfortable assembler source code using the programmer's reference as a starting point for a particular API (in this case CreateFile).

***************************  Found in Programmer's Reference ************************
HANDLE CreateFile(
  LPCTSTR lpFileName,
  DWORD dwDesiredAccess,
  DWORD dwShareMode,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  DWORD dwCreationDisposition,
  DWORD dwFlagsAndAttributes,
  HANDLE hTemplateFile
);

So lets take this information and make the following translation:-

  • Remove all the "types" for example LPCTSTR, DWORD etc (we don't need all this because the assembler knows that each parameter is always a dword and it does not type-check)
  • Remove the return value HANDLE (again we don't need this because we know the return is always in the EAX register and we don't need to type-check)
  • Remove the brackets and semi-colon
  • Add INVOKE and any required continuation characters
  • Add ADDR for pointers to addresses in memory and square brackets if memory is being addressed directly (leaving equates as they are)

then we end up with:-
INVOKE CreateFile,ADDR FileName,dwDesiredAccess,dwShareMode,\
  ADDR SecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, [hTemplateFile]


and we also need to ensure that GoAsm understands what all these parameters actually mean, so we need to declare
them in the DATA SECTION (in the case of equates they must be declared earlier in the file), so we add:-

SecurityDescriptor DB 20 DUP 0
SecurityAttributes DD 0Ch
                          DD SecurityDescriptor
                          DD 0
hTemplateFile DD 0
Filename DB 384 DUP 0
GENERIC_READ=80000000h
dwDesiredAccess=GENERIC_READ
FILE_SHARE_READ=1
dwShareMode=FILE_SHARE_READ
OPEN_EXISTING=3
dwCreationDisposition=OPEN_EXISTING
FILE_ATTRIBUTE_NORMAL=80h
dwFlagsAndAttributes=FILE_ATTRIBUTE_NORMAL
CreateFile=CreateFileA


This still seems unnecessarily complicated, so lets reduce it to
INVOKE CreateFileA,ADDR FileName,GENERIC_READ,FILE_SHARE_READ,\
  0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, [hTemplateFile]


The only declarations now required are:-

hTemplateFile DD 0
Filename DB 384 DUP 0
GENERIC_READ=80000000h
FILE_SHARE_READ=1
OPEN_EXISTING=3
FILE_ATTRIBUTE_NORMAL=80h


and finally lets strip out all the equates altogether:-
INVOKE CreateFileA,ADDR FileName,80000000h,1,0,3,80h,[hTemplateFile]   ;create an existing shared file for read access only


In this streamlined code the only declarations required are:-

hTemplateFile DD 0
Filename DB 384 DUP 0


Note that in none of the examples above is any include file needed.

You can see that INVOKE is designed to emulate a "C" type call, to make it easier to follow the API documentation (the specifications for Create File in the programmer's reference are all written as "C" type calls).
So, Chip, your plan to use INVOKE to call CreateFile was a good one, but the parameters are the wrong way round.  INVOKE works like CALL except that the parameters are reversed.
Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)

Chip

Jorgan,

Thnk you for your quick reply!  (especially at 2:00am, my time - Smile)

I was hoping that the control structures would be grouped together.   This has been my
(dated) experience in other operating systems.  These "include" type records were always
visable, hence self-documenting.

At least, I know that I can start with the programmers reference and proceed from there.

I have never used "C", but after awhile, all program coding seems the same,  with the
exceptiion of syntext.  Actually, the last program that I wrote in Assembler was 30 years
ago for the IBM 360 mainframes.  The registers are bigger and more plentiful, but the
concepts have not changed - only changed thier names.

By the way, your documentation and explanations have been a big help!  By focusing on
the underlying logic, you have enabled me to say "Ahah!, that's what that term means"
And, that mysterious term or concept turns out to be something that I can relate to,
having used it in many other operating systems and programming languages.

Thanks,

Chip

PS.  Actually, I never say "Ahah!",  but the phrasing does seem appropiate.   It has the
same number of letters as my true phrase - which would get me kicked off of this forum
if said here.  Smile
I am on Skype under my email address!