News:

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

Using the invoke statement

Started by Robert Collins, December 23, 2004, 12:31:40 AM

Previous topic - Next topic

Robert Collins

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?


donkey

#1
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.
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

raymond

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
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

John

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

Robert Collins

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.

John

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.

Jimg

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

MANT

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

Robert Collins

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

hutch--

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.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

drarem

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

Vortex

Hi Robert,

There are some macro tricks enabling you to use the statements below with Masm:
MessageBox,0,ADDR msg,ADDR capt,MB_OK

Vortex

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]

Robert Collins

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?

pbrennick

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