Hey everybody,

Sometimes I get an error while assembling:

error a2133: register value overwritten by invoke

The invoke in question looks like this:


invoke SetStyle,hDC,eax,addr hFont

Now, if I replace eax by something else it will work. Thing is, I don't care that eax gets overwritten, but it won't let me assemble anyways. And there are plenty of times when I invoke with eax as a parameter and the assembly doesn't care. What's going on? How can I get around this? Already tried pushing the instructions and then calling, but push doesn't resolve addr hFont unless I do it manually...

Well, talk to you all later

Posted on 2002-04-20 13:02:40 by chorus
Now you know why NASM was made, and many hate invoke! :) Assembly isn't one of the languages where you want stuff happening behind your back, but these things can be understood so you know what is happening.

invoke SetStyle,hDC,eax,addr hFont

The ADDR is what is doing it. 'ADDR hFont' really means:

lea eax, hFont
push eax

So now you see, that the invoke destroys the EAX value!
You could fix it yourself with:

lea edx,hFont
invoke SetStyle,hDC,eax,edx
Posted on 2002-04-20 13:10:02 by bitRAKE
thanks bitRake... didn't know that :)

Now...back to my code... :)

Posted on 2002-04-20 13:33:29 by chorus
Or you can push the values yourself if you want to have complete control :)

invoke SetStyle,hDC,eax,addr hFont

is a nice way of writing

lea edx,hFont
push edx
push eax
push hDC
call SetStyle
Posted on 2002-04-20 14:58:13 by _js_
If your really insane you could do:
_push MACRO val:REQ

push val
base = base + 4

_push esp
_push eax
_push [_hDC + base + esp]
add DWORD PTR [esp + 8], base + _hFont
call SetStyle
base = base - 12
This assumes hFont is a LOCAL or passed parameter.
No need to use EBP - that is so 1980's. :) Maybe, hDC
will be in a register as well?
Posted on 2002-04-20 15:13:03 by bitRAKE
bitRAKE: In the PNGlib code I used esp instead of ebp for the decoder (you've probably seen this already), as I needed as much registers as possible. I used the same thing as you did with the base value.

For those interested:

stk_c = 0
pPNGInfo textequ <dword ptr [esp+DEC_LOCAL_SIZE+stk_c+4]> ;1st parameter
curIDATlength textequ <dword ptr [esp+stk_c+0000]> ;length of current IDAT chunk data
isLastBlock textequ <dword ptr [esp+stk_c+0004]> ;set if last deflate block
nHLIT textequ <dword ptr [esp+stk_c+0008]> ;number of literal codes
lpMaxInput textequ <dword ptr [esp+stk_c+1244]> ;used in safe mode, max input pointer
lpMaxLUPointer textequ <dword ptr [esp+stk_c+1248]> ;used in safe mode, max lookup table pointer
lpCurDecBlockStart textequ <dword ptr [esp+stk_c+1252]> ;used in safe mode, start of decoded data for current block
lpStartOutput textequ <dword ptr [esp+stk_c+1256]> ;start of output data

The stk_c value is the stack correction value, whenever a value is pushed, stk_c is increased by 4 (or 2 if it's a word), a pop will decrease it by 4. BitRAKE's macro will do this automatically.

With the above setup I could access the parameters and locals without too much trouble.

Posted on 2002-04-20 16:34:00 by Thomas

The simplest solution when you get this problem is to use a memory variable to hold the value rather than using the register as a parameter when using invoke.


; code to load value in var

invoke Function,var,ADDR hFont

If the values loaded into "var" are only transient, you can reuse the variable in the code if you wish as it saves using extra stack parameters.


Posted on 2002-04-20 17:26:53 by hutch--
heh... it seems there are quite a lot of ways to do the same thing :) Ain't programming great?

hutch--, what you actually pointed out was how I was getting around the problem in the first place. I just figured there must be a better solution. Saving eax to a local works, but it also happens to be the return value from the function before so I thought it would be convenient to not have to do that. Currently, I'm doing as bitRake originally suggested. ie. lea edx,addr hFont/invoke SetStyle,hDC,eax,edx

didn't know that addr [4*ecx+eax] just converted to lea eax, [4*ecx+eax]... thought that you could just push [4*ecx+eax] and the processor addressing would figure it out. I guess you can't though :)

_js_, thanks, but I don't know if I need *that* much control over my code :)

ciao guys

Posted on 2002-04-20 19:08:03 by chorus