In C/C++ I can do this:
MessageBox, 0, "This is the body text", "This is the Caption text", MB_OK;
So, how come in Assembly I have to use variable names:
invoke MessageBox, 0, TextMsg, CaptionMsg, MB_OK
Cannot the MASM deal with inline data?
I believe that there is a macro in the masm32 project that does that (CSTR or something like that). If not then GoAsm handles them inherently, even Unicode if that is necessary...
Quote from: From the GoAsm manualGoAsm supports an extension of the PUSH mnemonic which is very helpful when programming in Windows. Often in Windows you need to send to an API a parameter which is a pointer to a null-terminated string for example:-
MBTITLE DB 'Hello',0
MBMESSAGE DB 'Click OK',0
PUSH 40h, ADDR MBTITLE, ADDR MBMESSAGE, [hwnd]
CALL MessageBoxA
To make this easier GoAsm permits the use of PUSH like this:-
PUSH 40h,'Hello','Click OK',[hwnd]
CALL MessageBoxA
or if you prefer to use INVOKE:-
INVOKE MessageBoxA, [hwnd],'Click OK','Hello',40h
You can also use this with Unicode strings as follows:-
PUSH 40h,L'Hello',L'Click OK',[hwnd]
CALL MessageBoxW
INVOKE MessageBoxW, [hwnd],L'Click OK',L'Hello',40h
The strings are added to the data section if there is one, if not then to the const section. This is in order that it does not create any new sections, adding 512 bytes to your executable. I imagine the MASM macro will add them to the data section regardless of whether one exists or not.
When you code it in C/C++, whatever you put between quotation marks gets compiled as data in memory and code is then added to access that data through a pointer because that is what is required by the function.
Some people have written macros to simulate that behaviour, but if you disassemble the produced code and study it, you would find that a pointer has been pushed for the parameter.
Raymond
There is a well known and widely use macro called szText that will allow you to create a new string at the procedure level. It looks like this:
szText MACRO Name, Text:VARARG
LOCAL lbl
jmp lbl
Name db Text,0
lbl:
ENDM
And is used like so:
szText TheMsg,"Assembler, Pure & Simple"
invoke MessageBox,hWin,ADDR TheMsg,ADDR szDisplayName,MB_OK
There is also the MsgBox macro that allows you to use VB style code for your message box. You can find that in Macros.asm from the MASM32 package.
John
Quote from: John on December 23, 2004, 01:21:32 AM
There is a well known and widely use macro called szText that will allow you to create a new string at the procedure level. It looks like this:
szText MACRO Name, Text:VARARG
LOCAL lbl
jmp lbl
Name db Text,0
lbl:
ENDM
And is used like so:
szText TheMsg,"Assembler, Pure & Simple"
invoke MessageBox,hWin,ADDR TheMsg,ADDR szDisplayName,MB_OK
I hope this helps you.
Well, it's not bad, but still the invoke statement uses a named variable. I guess from what I have seen posted that the bottom line is that one cannot use in-line qouted data in the invoke statement.
By the way, is it possible to use a macro within a macro? Such as in the following:
invoke MessageBox, 0, szText TheMsg, 'Assembler, Pure & Simple', szText DisplayName 'My Message Box', MB_OK ?
Probably not, that looks kind of funky.
Sorry for editing my post on you there, I tend to do that alot for some reason. :)
The MsgBox macro will allow you to use plain text in the call and if you find any other APIs where you need to do something like that you can write your own macro following the MsgBox macro as an example. Then add it to your own custom macros.asm file that you include in all your programs.
IIRC invoke is actually just a built in macro that does type (parameter?) checking on a prototyped function. Vortex wrote his own version of the invoke macro and posted it in the Laboratory. Maybe that will interest you.
I normally use these macros:
literal MACRO quoted_text:VARARG
LOCAL local_text
.data
local_text db quoted_text,0
.code
EXITM <local_text>
ENDM
sadd MACRO quoted_text:VARARG
EXITM <ADDR literal(quoted_text)>
ENDM
sadd equ SADD
Then you just
invoke MessageBox,hwin,sadd ("This is a test"),sadd("Did we pass???"),MB_ICONWARNING
I use pretty much the same macro, but I call it _T to simulate the _T macro used in VC++/MFC.
invoke MessageBox, hwin, _T("This is a test"), _T("Did we pass???"), MB_ICONWARNING
Quote from: John on December 23, 2004, 01:46:46 AM
Sorry for editing my post on you there, I tend to do that alot for some reason. :)
The MsgBox macro will allow you to use plain text in the call and if you find any other APIs where you need to do something like that you can write your own macro following the MsgBox macro as an example. Then add it to your own custom macros.asm file that you include in all your programs.
IIRC invoke is actually just a built in macro that does type (parameter?) checking on a prototyped function. Vortex wrote his own version of the invoke macro and posted it in the Laboratory. Maybe that will interest you.
I tried using the MsgBox macro as you indicated, MsgBox, 0, "text1", "text2", MB_OK but still got assembler syntax errors on it.
Also, I tried using Vortex's _include macro but again had assembler syntax errors _include MessageBox, 0, "text1", "text2", MB_OK
MASM using a macro included in the MASM32 project.
fn MessageBox, 0, "This is the body text", "This is the Caption text", MB_OK
MASM is a MACRO assembler, it is designed to do this type of thing.
There's also the CTEXT macro which can be used with invoke:
CTEXT MACRO y:VARARG
LOCAL sym, dummy
dummy EQU $ ;; MASM error fix
CONST segment
IFIDNI <y>,<>
sym db 0
ELSE
sym db y,0
ENDIF
CONST ends
EXITM <OFFSET sym>
ENDM
invoke MessageBox, NULL, CTEXT("This is a test"), CTEXT("TITLE"), MB_OK
Hi Robert,
There are some macro tricks enabling you to use the statements below with Masm:
MessageBox,0,ADDR msg,ADDR capt,MB_OK
Here is an example:
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include stcall.inc
include kernel32.inc
include user32.inc
include ctext.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.code
start:
MessageBox, NULL,CTEXT("MsgBoxText"), CTEXT("MsgCaption"), MB_OK
ExitProcess,NULL
END start
[attachment deleted by admin]
Quote from: Vortex on December 24, 2004, 07:23:47 PM
Here is an example:
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include stcall.inc
include kernel32.inc
include user32.inc
include ctext.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.code
start:
MessageBox, NULL,CTEXT("MsgBoxText"), CTEXT("MsgCaption"), MB_OK
ExitProcess,NULL
END start
I got it to work without the include stdcall.inc file. Is there some reasom why you are including it?
Vortex,
In my opinion, this is a lot simpler:
Quote.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
CTEXT MACRO y:VARARG
LOCAL sym, dummy
dummy EQU $ ;; MASM error fix
CONST segment
IFIDNI <y>,<>
sym db 0
ELSE
sym db y,0
ENDIF
CONST ends
EXITM <OFFSET sym>
ENDM
.code
start:
invoke MessageBox, NULL,CTEXT("MsgBoxText"), CTEXT("MsgCaption"), MB_OK
invoke ExitProcess,NULL
END start
I am not sure why someone would want to go through all that trouble just to remove to invokes. This is done all in one file as opposed to eleven files using over 100k. Maybe I am missing the big picture?
Paul
Hi pbrennick,
One you create the necessary include files, you can use them to call API functions without needing of invoke macro. The ide behind removing invoke is to call functions like in HLLs. This macro system is a good programming exercise for me, it's a matter of personal preference to use this methode.
Hi Robert,
I am not sure that you can build the executable without the stcall macro as it's used extensively in my macro system:
EXTERNDEF MessageBoxA@16:proc
MessageBox equ <stcall MessageBoxA@16,4>
Quote from: Vortex on December 25, 2004, 09:56:27 AM
Hi pbrennick,
One you create the necessary include files, you can use them to call API functions without needing of invoke macro. The ide behind removing invoke is to call functions like in HLLs. This macro system is a good programming exercise for me, it's a matter of personal preference to use this methode.
Hi Robert,
I am not sure that you can build the executable without the stcall macro as it's used extensively in my macro system:
EXTERNDEF MessageBoxA@16:proc
MessageBox equ <stcall MessageBoxA@16,4>
Hi Vortex,
Well, unless it is hidden from my view I can't see where the usage of the stdcall macro is. I don't think it is in the MACROS.ASM file. But below is the simple code to use the CTEXT macro and it works fine.
.386
.model flat, stdcall
option casemap:none
ExitProcess PROTO :DWORD
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
;
; Include only for the switch macro
;
include MACROS.ASM
CTEXT MACRO y:VARARG
LOCAL sym, dummy
dummy EQU $ ;; MASM error fix
CONST segment
IFIDNI <y>,<>
sym db 0
ELSE
sym db y,0
ENDIF
CONST ends
EXITM <OFFSET sym>
ENDM
.data
myvalue dd 25
.code
start:
mov eax,myvalue
switch (myvalue)
case 20
invoke MessageBox, 0, CTEXT("myvalue == 20"), CTEXT("The Answer Is"), MB_OK
case 23
invoke MessageBox, 0, CTEXT("myvalue == 23"), CTEXT("The Answer Is"), MB_OK
case 25
invoke MessageBox, 0, CTEXT("myvalue == 25"), CTEXT("The Answer Is"), MB_OK
endsw
invoke ExitProcess,0
END start
Robert,
Nice job and the case logic works very nicely. That is a method worth remembering. The following line is not necessary because it is already declared in kernel32.inc:
QuoteExitProcess PROTO :DWORD
Paul