I've been studying the code generated by the qeditor. I maybe finally starting to make sense of it.
Some questions if you please.
1) How do we know that the return value from a call to invoke will end up in eax?
2) Why is rv used here...
mov sHgt, rv(GetSystemMetrics,SM_CYSCREEN)
...but not here...
invoke LoadImage,hInstance,700,IMAGE_BITMAP,0,0, LR_DEFAULTSIZE or LR_LOADTRANSPARENT or LR_LOADMAP3DCOLORS
mov hBitmap, eax
...isn't the above the same thing as below?
mov hBitmap, rv(LoadImage,hInstance,700,IMAGE_BITMAP,0,0, LR_DEFAULTSIZE or LR_LOADTRANSPARENT or LR_LOADMAP3DCOLORS)
3) There's a lot to read out there on the net. Should I actually be reading "Intel® 64 and IA-32 Architectures Software Developer's Manual" or just using it as a dictionary? What should I be reading?
Quote from: NathanStiles on March 13, 2012, 05:39:03 PM
What should I be reading?
Click on my "tips & tricks" below, you'll find a concise list of stuff to read.
Welcome to the forum :thumbu
Quote from: NathanStiles on March 13, 2012, 05:39:03 PM
I've been studying the code generated by the qeditor. I maybe finally starting to make sense of it.
Qeditor is a
text editor.
What
code generated do you mean ?
Quote
Some questions if you please.
1) How do we know that the return value from a call to invoke will end up in eax?
Historically, each register in the in the CPU was given a meaningful name and was designated a specific purpose.
The AX register was designated the
Accumulator and was assigned the task of holding the return value of a function call.
The AX register is comprised of AH and AL. In 32 bit systems AX is extended to EAX.
Quote
2) Why is rv used here...
mov sHgt, rv(GetSystemMetrics,SM_CYSCREEN)
A call to GetSystemMetrics returns a simple integer value.
Quote
invoke LoadImage,hInstance,700,IMAGE_BITMAP,0,0, LR_DEFAULTSIZE or LR_LOADTRANSPARENT or LR_LOADMAP3DCOLORS
mov hBitmap, eax
A call to LoadImage returns a HANDLE.
Quote
...isn't the above the same thing as below?
Because different macros are being used.
Quote
3) What should I be reading?
Any good book about MASM Assembly Language Programming.
http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Dstripbooks&field-keywords=masm+assembly+language
edit:
Additional links:
http://win32assembly.online.fr/tutorials.html
http://webster.cs.ucr.edu/AsmTools/MASM/index.html
http://homepage.mac.com/randyhyde/webster.cs.ucr.edu/www.artofasm.com/index.html
@jj2007 thank you I will review the link you provided
@SteveAsm Thank you for responding. If you run \masm32\qeditor.exe click the code menu it will generate a simple windows project template for you.
I have in .data?
hBitmap dd ?
sHgt dd ?
so sHgt is the int and hBitmap is the handle i know they're different things but it's still 4bytes each right?
They're allocated the same way. I don't see the difference.
Even when I changed the code and assembled and linked etc (makeit.bat) it all worked the same no errors warnings etc.
It seems that the rv macro is taking the return value from eax right?
So invoke is a macro?
Quote from: NathanStiles on March 13, 2012, 06:33:40 PM
I have in .data?
hBitmap dd ?
sHgt dd ?
so sHgt is the int and hBitmap is the handle i know they're different things but it's still 4bytes each right?
They're allocated the same way. I don't see the difference.
Even when I changed the code and assembled and linked etc (makeit.bat) it all worked the same no errors warnings etc.
It seems that the rv macro is taking the return value from eax right?
So invoke is a macro?
Yes.
I the above case:
hBitmap dd ?
sHgt dd ?
both are assigned the same memory size, as DWORD. That's what dd means.
where db would be BYTE, dq would be QWORD.
The difference is in their name. Each variable has it's own unique name.
In this case, the name is descriptive of what it is.
hBitmap means: Handle to Bitmap.
sHgt is an integer value that represents the Y axis of the screen.
When calling the function GetSystemMetrics, you provide it with a single parameter which you wish to query.
In this case, (GetSystemMetrics,SM_CYSCREEN) is asking the system what is the Y dimension of the screen (in terms of X and Y).
sHgt is the value of Y.
And Yes, invoke is a macro.
There are macros intrinsic to MASM (meaning built-in) and there are additional macros in Masm32.
Don't confuse MASM with Masm32. They are two different things.
MASM is the assembler, Masm32 is a library for use with MASM.
If you read the MASM manuals/books they will provide a list of built-in macros.
Quote from: NathanStiles on March 13, 2012, 06:33:40 PM
@jj2007 thank you I will review the link you provided
@SteveAsm Thank you for responding. If you run \masm32\qeditor.exe click the code menu it will generate a simple windows project template for you.
I have in .data?
hBitmap dd ?
sHgt dd ?
so sHgt is the int and hBitmap is the handle i know they're different things but it's still 4bytes each right?
They're allocated the same way. I don't see the difference.
Even when I changed the code and assembled and linked etc (makeit.bat) it all worked the same no errors warnings etc.
It seems that the rv macro is taking the return value from eax right?
So invoke is a macro?
yes - they are all dword in
size - that does not necessarily satisfy the
type definition
in asm code, we can be sloppy, as long as we know what type of data is stored someplace :P
but in C code, the typing is stronger - meaning that if you try to put a handle where a uint goes, the compiler may not cooperate
much of what we write in asm is closely related to C because MS has defined their functions that way
so, if i wanted to be "more correct", i could use stronger typing
hBmp HANDLE ?
if you look in windows.inc, you will find that Hutch has provided the TYPEDEF statements for numerous data types
HANDLE TYPEDEF DWORD
so - it's a dword, either way :bg
INVOKE is a macro, but not defined in the include or macro files
instead, it is internal to the MASM assembler
"rv" is a macro that returns a value - it is simply a shortcut
"func" is a similar shortcut that allows direct use of strings where the function requires a pointer
that macro defines the string in the data area and passed the pointer
those macros can be examined by looking in masm32\macros\macros.asm
most windows functions return a result or status in EAX
if you want to see what it is, you can use MSDN as a reference
for example, if you google "CreateWindowEx", one of the first hits will be the MSDN page for that function
http://msdn.microsoft.com/en-us/library/windows/desktop/ms632680%28v=vs.85%29.aspx
scroll down to the "Return Value" section for a description
a little more info on register usage in windows functions...
as i mentioned above, most windows API functions return a status or result in EAX
from that, you may infer that the EAX register is not preserved across the call :P
this is also true for ECX and EDX - they may be trashed by the function
also true for FPU/MMX registers and SSE - anybodies guess - lol
however, the EBX, ESI, EDI, and EBP registers are preserved across system cals
also, the direction flag (DF) should be cleared when calling a system function
so - if you set it, you should clear it when done
while it is not a requirement, we generally try to write our functions following the same set of rules
that makes the code "re-usable" in an environment where it may be called from a callback like WndProc
although MS never seems to use ECX or EDX to pass information (C compilers aren't set up that way),
we may use these registers that way in our own functions, if desired
i sometimes return a status in EAX, count in ECX, and pointer in EDX
as i write more functions, i am learning that it is nice to return all 3 registers in some known state
if there isn't anything to return in ECX and/or EDX, i may set them to 0 or return one of the passed parameters
this tends to make the function more flexible, and minimizes any future changes i may have to make
here is an example
the masm32 library has a console CLS function, but i wanted one that would handle multiple pages
so - i wrote one that requires a handle
while i'm at it, i return some values in EAX, ECX, EDX...
;***********************************************************************************
OPTION PROLOGUE:None
OPTION EPILOGUE:None
ConCls PROC hConsole:HANDLE
;Clear Console Screen Buffer, DednDave 12-2011
;
; This function allows the use of multiple screen buffers, clearing
;only the buffer specified by hConsole. Space characters and the current
;foreground/background attributes for the specified buffer are used.
;
;Call With: hConsole = handle of console screen buffer to clear
;
; Returns: EAX = screen position (0,0)
; ECX = total number of characters in screen buffer
; EDX = buffer character attributes used to clear
;
; Uses: all other registers preserved
push ebx
push edi
mov ebx,[esp+12] ;EBX = hConsole
xor edi,edi
sub esp,(sizeof CONSOLE_SCREEN_BUFFER_INFO+3) and -4
INVOKE GetConsoleScreenBufferInfo,ebx,esp
movzx eax,word ptr [esp].CONSOLE_SCREEN_BUFFER_INFO.dwSize.x
movzx edx,word ptr [esp].CONSOLE_SCREEN_BUFFER_INFO.dwSize.y
mul edx
push edx
INVOKE FillConsoleOutputCharacter,ebx,32,eax,edi,esp
pop eax
movzx edx,word ptr [esp].CONSOLE_SCREEN_BUFFER_INFO.wAttributes
push edx
push eax
INVOKE FillConsoleOutputAttribute,ebx,edx,eax,edi,esp
INVOKE SetConsoleCursorPosition,ebx,edi
pop ecx
pop edx
xchg eax,edi
add esp,(sizeof CONSOLE_SCREEN_BUFFER_INFO+3) and -4
pop edi
pop ebx
ret 4
ConCls ENDP
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
;***********************************************************************************
[smartass]
Handles are void pointers and the correct definition is:
PVOID typedef ptr
HANDLE typedef PVOID
This declaration would work for 32 and 64 Bit platforms
[/smartass]
:bg
....and still, it's a dword :lol
@qWord so using the method you mentioned keeps me from having to replace DWORD declarations used for pointers if my code should be built as 64bit? Where/how is ptr defined?
@dedndave that code a bit more than I can understand at this point but I apprecate the other information :D I did notice the OPTION and remembered reading that directive "documentation" on MSDN yesterday. Sadly the options are not explained. I didn't get to review all the information presented to me in this thread yet but I assume I will eventually be interested in the OPTION directive and it's uses.
@steveasm thank you again
I'm a bit spoiled by VisualStudio and `go to definition`. Is there some IDE that I can use to perform tasks like that for ASM?
There is a little confusion going on here, a HANDLE is a unique ID for a target which can be may different things, memory reference, ID for a system defined window, a GDI object and so on.
The SIZE of a handle is determined by the operating system version, in 16 bit Windows it was WORD (2 bytes), in 32 bit Windows it is DWORD (4 bytes),in later version it is larger again and I have no doubt that when the 256 bit Version of Windows/Linux/Whatever appears it will be bigger again.
The reason why an assembler works in generic data sizes is because it works in processor registers and they are determined purely by their SIZE. C/C++ #defines and TYPEDEFs are equates to native data sizes of registers for the hardware that the OS version runs on.
hi Nathan
MSDN may not be the best place to find info about OPTION
the masm manual is available...
http://www.4shared.com/zip/lCNJTTZk/MASM_61_Manuals_High_Quality_P.html
dedndave that's version 6.1, just about the same version distributed with the masm32 library. The last version in VS2010 is 10 I remember reading that certain ssse2(I think) instructions aren't supported in that 6.1 version how much is really different in 10 vs 6?
well - the biggest difference is probably the level of SSE support
most of the syntax definitions have remained unchanged
MS seems to have updated masm a few times without updating the reference :P
however, there is some reference material on MSDN
Nathan,
If you have ML version 10 or 11, just use it as its compatible with code written for older versions.