Here's the macro:



M_MOV macro a:req,b:req
if ((opattr(a)) and 00010000) or ((opattr(b)) and 00010000)
mov a,b
else
push b
pop a
endif
endm


I tested it in a simple exe using the /EP compiler switch to see if it did the right thing and it worked fine.

Now I used the macro in the following proc but it used the MOV block instead of the PUSH/POP block.



SetErrorCallback proc _callback:dword
M_MOV g_err.callback,_callback
ret
SetErrorCallback endp


The g_err structure is external and the proc is in a file of its own and is being compiled into a library.

Any ideas?

Maelstrom

:confused:
Posted on 2002-01-28 23:49:12 by Maelstrom
This is straight from the MASM manual:
[i]OPATTR serves as an enhanced version of the .TYPE operator,

which returns only the low byte (bits 0 ? 7) shown in the table.
Bits 11 ? 15 of the return value are undefined.[/i]

[u]Bit Set If expression[/u]
0 References a code label
1 Is a memory variable or has a relocatable data label
2 Is an immediate value
3 Uses direct memory addressing
4 Is a register value
5 References no undefined symbols and is without error
6 Is relative to SS
7 References an external label
8 ? 10 [u]Has the following language type[/u]:
000 ? No language type
001 ? C
010 ? SYSCALL
011 ? STDCALL
100 ? Pascal
101 ? FORTRAN
110 ? Basic
But my tests give a more detailed view of the above text:
Tester 5			;; 36 ;; 000 0010 0100 ;; Constant

Tester Testx ;; 36 ;; 000 0010 0100 ;; structure
Tester DWORD ;; 36 ;; 000 0010 0100 ;; type
Tester eax ;; 48 ;; 000 0011 0000 ;; register
Tester WinMain ;; 37 ;; 000 0010 0101 ;; Label
Tester _CODE ;; 32 ;; 000 0010 0000 ;; segment
Tester [eax + ecx] ;; 34 ;; 000 0010 0010 ;; data indirect
Tester BigNumber ;; 42 ;; 000 0010 1010 ;; data direct
Tester [esp] ;; 98 ;; 000 0110 0010 ;; stack relitive
Tester Watt ;; 0 ;; 000 0000 0000 ;; <unknown/error>
Tester 1.5e2 ;; 0 ;; 000 0000 0000 ;; float value
Tester PublicMessage1 ;;933 ;; 011 1010 0101 ;; ?
Tester REAL10 1.5 ;; 36 ;; 000 0010 0100 ;; #
Tester is just a macro that outputs the value of OPATTR. The code should work, but I'd have to see the context and run some test. Post a section of code that produces the problem and I'll see what I can do.
Posted on 2002-01-29 00:17:24 by bitRAKE
bitRAKE

I've attached some code that shows the problem. I've played a bit more with it and it looks like it's the EXTERNDEF that's causing the problems but I'm not 100% sure.

In case it does work for you, look at the _BuildOriginal.txt file to see what my output was.

Maelstrom

Edit :: Whoops - forgot the macro include
Posted on 2002-01-29 19:09:29 by Maelstrom
Wow, the solution is real simple. :grin:
M_MOV macro a:req,b:req

if ((opattr(a)) and 00010000y) or ((opattr(b)) and 00010000y)
mov a,b
else
push b
pop a
endif
endm
You have to specify that the numbers are binary - I use a Y so it isn't confused with a hexadecimal B, but that works just as good.

Kind of feel silly that I didn't catch this earlier! :tongue:
Posted on 2002-01-29 23:00:31 by bitRAKE
why a 'Y'?
Posted on 2002-01-30 06:09:38 by dxantos
The Y signifies a binary number:

3 = 11y = 011b
Posted on 2002-01-30 09:12:52 by bitRAKE
Dxantos im with you here... ??? Im puzzled how this is suppose to make sence. :P

Buy Hey, Micr$soft are CrAzY people when they want to be. (look at windows ME).

NaN
Posted on 2002-01-31 16:59:37 by NaN
They use B, too. But it conflicts with hex numbers.
It's not that crazy. You can use this, too:

.RADIX 2
db 11 ; this equals 3 in decimal, not 11!
.RADIX 10
Posted on 2002-01-31 17:07:21 by bitRAKE
For some reason, some programmers thought it was neat to default the radix to something other than 10. The bugs came when the radix was 16 (hex).

.radix 16
a1 db 1a
a2 db 1b ; decimal 27 or binary 1 ?
a3 db 1c
a4 db 1d ; decimal 29 or decimal 1 ?
Posted on 2002-01-31 20:14:40 by tank