The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Ficko on June 21, 2010, 07:20:11 AM

Title: Assembler time type query..?
Post by: Ficko on June 21, 2010, 07:20:11 AM
Is it possible to get the exact type of a variable not just "is a memory reference"?

I wanna know is "SDWORD", "DWORD" etc. ::)
Title: Re: Assembler time type query..?
Post by: donkey on June 22, 2010, 05:43:17 AM
Assuming that you are enumerating the labels in a debug build, perhaps, the pdb file format (used with MASM debug builds) may store that information, the tags that are stored can be found in the SymTagEnum enumeration. (http://msdn.microsoft.com/en-us/library/bkedss5f%28VS.80%29.aspx) There are many type related enums but since I have not tried them (they don't directly apply to GoAsm since that assembler uses COFF based labels) I am not sure that they actually specify data width.
Title: Re: Assembler time type query..?
Post by: sinsi on June 22, 2010, 06:26:37 AM
Things like sdword/dword are usually dependent on context, how the value is used. Programs like IDA can mostly tell by how it's used, but unless you have the source "it's all dwords".
donkey, they would only show up in a .pdb if they are declared public/externdef wouldn't they?
Title: Re: Assembler time type query..?
Post by: Ficko on June 22, 2010, 06:58:46 AM
Thanks Donkey & sinsi!

I think I didn't express too well what I am looking for. :red

I like to get during assembler time this data.
With ".TYPE" or "OPATTR" you can get only a "hint" but the assembler surely knows the exact type.

I just wondering that there is a "trick" you can substract this information.
Like behind for example "DWORD" is surely an enum value.
If I could get that associated with a variable it would be enough. :bg
Title: Re: Assembler time type query..?
Post by: sinsi on June 22, 2010, 07:14:28 AM
Well, there are only 16 bits in the return value, and 4 aren't used (11-15) so it's a bit limited.
Is this a macro thing? How are you trying to use it?
Title: Re: Assembler time type query..?
Post by: Ficko on June 22, 2010, 07:23:23 AM
Quote from: sinsi on June 22, 2010, 07:14:28 AM
Well, there are only 16 bits in the return value, and 4 aren't used (11-15) so it's a bit limited.
Is this a macro thing? How are you trying to use it?

Yes is a macro thing.
I know I can't do it purely with "OPATTR" but I thought maybe after I filtered out it is a memory reference maybe there is a way to get some more info out of MASM about it. ::)

I like to know in the macro that the param is a "REAL4/8" "S/DWORD/QWORD".
Title: Re: Assembler time type query..?
Post by: MichaelW on June 22, 2010, 07:31:18 AM
Quote from: Ficko on June 22, 2010, 06:58:46 AM
but the assembler surely knows the exact type

At least for simple variables I think the assembler only knows the size, so it sees DWORD, SDWORD, and REAL4 as all of the same "type". So for example the assembler will let you use Invoke to pass a DWORD to a procedure where the parameter is declared as a SDWORD, or use a DWORD as an operand for the FLD instruction.

Title: Re: Assembler time type query..?
Post by: Ficko on June 22, 2010, 07:39:47 AM

At least for simple variables I think the assembler only knows the size...


I am not sure about that since if you declare at the proc - MyPoc proc Param1:SDWORD -
You can use it like - if (Param1 < 0) - will be eq to - if (SDWORD PTR Param1 < 0) -

Looks like the assembler do keeps track on it at least at local level. ::) 
Title: Re: Assembler time type query..?
Post by: jj2007 on June 22, 2010, 07:48:44 AM
Quote from: Ficko on June 22, 2010, 07:23:23 AM
I like to know in the macro that the param is a "REAL4/8" "S/DWORD/QWORD".

Sounds familiar :bg
The MasmBasic Str$() eats all kinds of valid numbers; for example, regs are identified with opattr, then you can check if xmm is part of the text of the arg. Others can be identified by their size:
RealSize = SIZEOF arg   ;; 4 for DWORD, 10 for REAL10
TextSize SIZESTR arg      ;; 2 for ax, al, 3 for eax, 4 and higher for xmm2, xmm(1) etc
But like you, I have not yet found a sound way to distinguish a REAL4 from a DWORD, and a REAL8 from a QWORD, so I work with s: and q: prefixes for the less frequent variants. As you write, the assembler does have that information. Tickling it out is the problem...

Print Str$(ebx) ; simple
Print Str$(MyReal10) ; works for most kinds of arguments
Print "Real4: ", Str$(s:MyR4) ; Real4 variables need the s: prefix in Str$
Print "qWord: ", Str$(q:MyQword) ; qwords need the q: prefix; see also edx::eax in remarks
Print "SSE2: ", Str$("Xmm0=%i", xmm0) ; you can print xmm registers directly
Title: Re: Assembler time type query..?
Post by: Ficko on June 22, 2010, 08:09:42 AM
Thanks  jj2007! :wink

That's solves some of my problems.

I am wondering that MASM internal macros like - .if .else .endif - are written as "real" macros?

That would mean there is a way to do it just not published by MS. ::) :bg
Title: Re: Assembler time type query..?
Post by: MichaelW on June 22, 2010, 10:06:42 AM
Now that I test, in the context of the high-level syntax the assembler knows that SBYTE, SWORD, and SDWORD are signed, but this does not necessarily indicate that it knows these type details in other contexts or for other types. I can't see any good reason for Microsoft to provide some of the internally available type information through the OPATTR and similar operators and withhold other information.
Title: Re: Assembler time type query..?
Post by: jj2007 on June 22, 2010, 10:09:10 AM
Here is an excerpt from chapter eight of Randall Hyde's Art of Assembly (http://maven.smith.edu/~thiebaut/ArtOfAssembly/CH08/CH08-5.html) that suggests a method to distinguish WORD and SWORD:

QuoteThe type operator returns a constant that is the number of bytes of the specified operand. For example, type(word) returns the value two. This revelation, by itself, isn't particularly interesting since the size and sizeof operators also return this value. However, when you use the type operator with the comparison operators (eq, ne, le, lt, gt, and ge), the comparison produces a true result only if the types of the operands are the same. Consider the following definitions:

Integer         typedef word
J               word    ?
K               sword   ?
L               integer ?
M               word    ?

               byte    type (J) eq word        ;value = 0FFh
               byte    type (J) eq sword       ;value = 0
               byte    type (J) eq type (L)    ;value = 0FFh
               byte    type (J) eq type (M)    ;value = 0FFh
               byte    type (L) eq integer     ;value = 0FFh
               byte    type (K) eq dword       ;value = 0

Testbed:

include \masm32\include\masm32rt.inc
include TrueType.inc

.data?
J dword ?
K sdword ?
R4 REAL4 ?

.code
start:
echo
TrueType J
TrueType R4
TrueType K
echo
.err
end start


Output:
J is an unsigned dword
R4 is a real 4
K is a signed dword
Gotcha :toothy
Now the bad news: JWasm fails miserably for this test  :(
Title: Re: Assembler time type query..?
Post by: qWord on June 22, 2010, 10:35:31 AM
that's great jj! Never thought that this is possible  :U
Quote from: jj2007 on June 22, 2010, 10:09:10 AMNow the bad news: JWasm fails miserably for this test :(
currently no problem for me  - most of my macros wont work with jwasm  ::)

qWord
Title: Re: Assembler time type query..?
Post by: Ficko on June 22, 2010, 10:46:03 AM
jj2007, that's awesome! :U

I knew it can be done!  :green
Title: Re: Assembler time type query..?
Post by: dedndave on June 22, 2010, 01:17:07 PM
if you have a string ?
will it return the type (byte) or the sizeof (string length) ?
Title: Re: Assembler time type query..?
Post by: qWord on June 22, 2010, 01:34:36 PM
Quote from: dedndave on June 22, 2010, 01:17:07 PMwill it return the type (byte) or the sizeof (string length) ?
the type.

I've also noticed that this is "official documented" in the MASM Programmer's Guide. This technique is shown in an example-macro for OPATTR:
Quoteload    MACRO reg:REQ, adr:REQ
    IF (OPATTR (adr)) AND 00010000y    ;; Register
        IFDIFI reg, adr                ;; Don't load register
            mov     reg, adr           ;;   onto itself
        ENDIF
    ELSEIF (OPATTR (adr)) AND 00000100y
        mov     reg, adr               ;; Constant
    ELSEIF (TYPE (adr) EQ BYTE) OR (TYPE (adr) EQ SBYTE)
        mov    reg, OFFSET adr         ;; Bytes
    ELSEIF (SIZE (TYPE (adr)) EQ 2
        mov    reg, adr                ;; Near pointer
    ELSEIF (SIZE (TYPE (adr)) EQ 4
        mov    reg, WORD PTR adr[0]    ;; Far pointer
        mov    ds,  WORD PTR adr[2]
    ELSE
        .ERR <Illegal argument>
    ENDIF
END
M
Title: Re: Assembler time type query..?
Post by: jj2007 on June 22, 2010, 02:01:40 PM
Quote from: dedndave on June 22, 2010, 01:17:07 PM
if you have a string ?
will it return the type (byte) or the sizeof (string length) ?

Add this to the macro:
else
oa = (opattr arg) AND 127
tmp$ CATSTR <arg>, < is something else with an opattr of >, %oa
% echo tmp$


MyStringPtr dd MyString
MyString db "Ok, so that's a string with 41 characters", 0

.code
start:
..
TrueType MyStringPtr
TrueType MyString
TrueType offset MyString


Output:
MyStringPtr is an unsigned dword
MyString is something else with an opattr of 42
offset MyString is something else with an opattr of 38
Title: Re: Assembler time type query..?
Post by: jj2007 on June 22, 2010, 06:09:45 PM
Quote from: qWord on June 22, 2010, 10:35:31 AM
most of my macros won't work with jwasm  ::)
If it's "most", the cause might be some specific programming habit of yours. I have a lot of odd and idiosyncratic macros in MasmBasic.inc, but until now they all work in JWasm and ml 6.15+
Anyway, I filed it as a bug in SourceForge (https://sourceforge.net/tracker/?func=detail&aid=3019705&group_id=255677&atid=1126895)
Title: Re: Assembler time type query..?
Post by: qWord on June 22, 2010, 09:20:33 PM
Quote from: jj2007 on June 22, 2010, 06:09:45 PMIf it's "most", the cause might be some specific programming habit of yours.
What habit should it be? - Currently there are still incompatibilities in jwasm. e.g.:
tm TEXTEQU <1>
bla TEXTEQU %1+tm ; error with jwasm

(also reported on SourceForge)
I've also tried to make the affected macros compatible, but when one error is 'solved' the next one comes up.
However, I'm very sure japhet will get them all  :8)
Title: Re: Assembler time type query..?
Post by: jj2007 on June 22, 2010, 09:29:47 PM
Quote from: qWord on June 22, 2010, 09:20:33 PM
Quote from: jj2007 on June 22, 2010, 06:09:45 PMIf it's "most", the cause might be some specific programming habit of yours.
What habit should it be? - Currently there are still incompatibilities in jwasm. e.g.:
tm TEXTEQU <1>
bla TEXTEQU %1+tm ; error with jwasm

(also reported on SourceForge)

Workaround:

include \masm32\include\masm32rt.inc

tm EQU 1
bla TEXTEQU %1+tm ; no error with jwasm

;tm TEXTEQU <1>
;bla TEXTEQU %1+tm ; error with jwasm

.code
start:
% echo zeBla: bla
exit
.err
end start

Quote
I've also tried to make the affected macros compatible, but when one error is 'solved' the next one comes up.
However, I'm very sure japhet will get them all  :8)

He is morally obliged to chase them, with such an enthusiastic audience :bg
Title: Re: Assembler time type query..?
Post by: jj2007 on June 23, 2010, 07:30:45 AM
Quote from: qWord on June 22, 2010, 09:20:33 PM
However, I'm very sure japhet will get them all  :8)

Japheth, 22.6.2010: It's fixed in v2.03

That means we can improve our macro collections soon :bg
Title: Re: Assembler time type query..?
Post by: Ficko on June 23, 2010, 12:42:53 PM
Due to we are winded up by JWASM I have here this little pain can get it work on JWASM. :bg
The %echo shows legitimate out put but JWASM doesn't like it any idea? ::)


.686p
.model flat, stdcall
option casemap :none
Pilot$_ PROTO C :DWORD,:VARARG
Pilot$ MACRO Params:VARARG
LOCAL pushed,Cn
pushed EQU <>
Cn = 0
FOR Param,<Params>
pushed CATSTR pushed,<,>,<Param>
Cn = Cn + 1
ENDM
%echo @CatStr(<invoke Pilot$_,>,<%Cn>,<pushed>)
@CatStr(<invoke Pilot$_,>,<%Cn>,<pushed>)
ENDM

.code
start:
Pilot$ eax,ebx
end start
Title: Re: Assembler time type query..?
Post by: jj2007 on June 23, 2010, 01:26:41 PM
Quote from: Ficko on June 23, 2010, 12:42:53 PM
Due to we are winded up by JWASM I have here this little pain can get it work on JWASM. :bg
The %echo shows legitimate out put but JWASM doesn't like it any idea? ::)

include \masm32\include\masm32rt.inc
.686p

Pilot$_ PROTO C :DWORD,:VARARG

Pilot$ MACRO Params:VARARG
LOCAL pushed,Cn
pushed EQU <>
Cn = 0
FOR Param,<Params>
pushed CATSTR pushed,<,>,<Param>
Cn = Cn + 1
ENDM
% echo @CatStr(<invoke Pilot$_,>,<%Cn>,<pushed>)
% @CatStr(<invoke Pilot$_,>,<%Cn>,<pushed>)
ENDM

.code
start:
Pilot$ eax, ebx
exit
Pilot$_ proc C args, more:vararg
invoke MessageBox, 0, chr$("Ciao"), chr$("Title"), MB_OK
ret
Pilot$_ endp

end start


By the way: It is considered good practice only examples that have been tested. Yours threw an error both with ML and JWasm.
Title: Re: Assembler time type query..?
Post by: Ficko on June 23, 2010, 01:46:05 PM
Thanks I would never figure that one out. :U

Quote
By the way: It is considered good practice only examples that have been tested. Yours threw an error both with ML and JWasm.

Noway dude. :bg
perhaps you had renamed your "JWASM.exe" to "ML.exe" a long time ago. :wink

Quote
invoke Pilot$_,2,eax,ebx
Microsoft (R) Macro Assembler Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.
Make finished.
Total compile time 78 ms
Title: Re: Assembler time type query..?
Post by: jj2007 on June 23, 2010, 01:59:30 PM
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

NewWin32.obj : error LNK2001: unresolved external symbol _Pilot$_
NewWin32.exe : fatal error LNK1120: 1 unresolved externals


For ml 9.0, 6.15 and 6.14, dude :bg
Title: Re: Assembler time type query..?
Post by: Ficko on June 23, 2010, 02:11:33 PM
May that's come from the linker ::)
Mine is :
Quote
Microsoft (R) Incremental Linker Version 10.00.30319.01
I never sad the program can be linked. :bg

But what the trick or rule with this "%" thing by JWASM?

I have this code and I do not wanna call my macro with "%" :naughty:


.686p
.model flat, stdcall
option casemap :none
MBMAIN = 1
POINTER  TYPEDEF DWORD
OPENCONSOLE__ PROTO :POINTER
; ------------------------------------------------
OPENCONSOLE_ MACRO CInfo:REQ
IF MBMAIN EQ 2
push CInfo
invoke AllocConsole
pop ecx
.if (eax != 0)
invoke OPENCONSOLE__,ecx
.endif
ELSE
invoke OPENCONSOLE__,CInfo
ENDIF
ENDM
; -----------------------
;; INLINE [nX] OPCODE,...
; -----------------------
inline equ <INLINE>
Inline equ <INLINE>
INLINE MACRO vs:VARARG
LOCAL pos
FOR arg,<vs>
IFNB <arg>
pos=@InStr(1,arg,<!:>)
argy CATSTR <arg>
IF pos
argy CATSTR <@SubStr(<arg>,1,pos-1),@SubStr(<arg>,pos+1)>
ENDIF
IFIDN @SubStr(<arg>,2,1),<X>
REPEAT @SubStr(<arg>,1,1)
@SubStr(%argy,4)
ENDM
ELSE
argy
ENDIF
ENDIF
ENDM
ENDM

.code
start:
;Inline push eax,OPENCONSOLE_ eax,pop eax
%Inline push eax,OPENCONSOLE_ eax,pop eax ;JWASM req %
end start
Title: Re: Assembler time type query..?
Post by: jj2007 on June 23, 2010, 02:28:08 PM
Same as before. It should throw an error because _OPENCONSOLE__ proc is not found.

*** Assemble using \Masm32\bin\ml /nologo /c /coff  /Fl /Sn /Fo "NewWin32" ***
Assembling: tmp_file.asm
*** Link using link with sub CONSOLE   "NewWin32.obj" /OUT:"NewWin32.exe" (no resources) ***

Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

NewWin32.obj : error LNK2001: unresolved external symbol _OPENCONSOLE__@4
NewWin32.exe : fatal error LNK1120: 1 unresolved externals
Title: Re: Assembler time type query..?
Post by: Ficko on June 23, 2010, 02:37:49 PM
You should not link it dude!  :wink

The point is to compile it.

I have about 80 macros here not compiling under JWASM.

You sad
Quote
If it's "most", the cause might be some specific programming habit of yours.

I thought might you right and I like to understand what is it and what can I do about it because I like JWASM due to it fixes over MASM but I just can't use it.
I write 10 macros and get 64 errors. :eek
Title: Re: Assembler time type query..?
Post by: jj2007 on June 23, 2010, 02:43:50 PM
Quote from: Ficko on June 23, 2010, 02:37:49 PM
You should not link it dude!  :wink

Schlaumeier :boohoo:
Title: Re: Assembler time type query..?
Post by: Ficko on June 23, 2010, 02:59:02 PM
Quote from: jj2007 on June 23, 2010, 02:43:50 PM
Schlaumeier :boohoo:

Grazie mi sapientone!  :U
Title: Re: Assembler time type query..?
Post by: dedndave on June 23, 2010, 07:29:14 PM
look at the bright side...
if i wrote 64 macros, i'd probably have 256 errors   :P
Title: Re: Assembler time type query..?
Post by: jj2007 on October 01, 2010, 03:28:45 PM
News from JWasm (https://sourceforge.net/tracker/?func=detail&aid=3078756&group_id=255677&atid=1126895) - the following problem has been fixed:

include \masm32\include\masm32rt.inc

GetArgType MACRO arg
LOCAL version$
if @Version eq 615
version$ equ <JWasm>
else
version$ equ <Masm>
endif
tmp$ CATSTR <The_arg = >, <arg>
% echo tmp$
if type(arg) eq REAL4
% echo version$ says it's a REAL4
elseif (type(arg) eq DWORD) or (type(arg) eq SDWORD)
% echo version$ says it's a DWORD, congrats!!
endif
ENDM

.code
start:
GetArgType dword ptr [edx]
.err
exit

end start


If only Microsoft would fix their bugs so speedily ::)