Is it possible to get the exact type of a variable not just "is a memory reference"?
I wanna know is "SDWORD", "DWORD" etc. ::)
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.
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?
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
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?
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".
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.
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. ::)
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
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
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.
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 :(
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
jj2007, that's awesome! :U
I knew it can be done! :green
if you have a string ?
will it return the type (byte) or the sizeof (string length) ?
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
ENDM
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
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)
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)
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
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.03That means we can improve our macro collections soon :bg
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
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.
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
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
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
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
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
Quote from: Ficko on June 23, 2010, 02:37:49 PM
You should not link it dude! :wink
Schlaumeier :boohoo:
look at the bright side...
if i wrote 64 macros, i'd probably have 256 errors :P
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 ::)