"the infamous "invoke" bug: using invoke with variables of type BYTE
(or WORD in 32bit code) causes bad code to be generated in MASM."
anyone know about this, and can confirm/deny/elaborate? i've never experienced this bug that i'm aware of, but I use invoke a lot actually with byte so it has me uncomfotable.
As far as I know, the "bug" is in the use of AL as a scratch register when passing a byte memory operand or 8-bit register other than AL.
CORRECTION: for 8-bit memory operands, eax is use as a scratch register.
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
b db 123
.code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
test1 proc arg:BYTE
ret
test1 endp
test2 proc arg:BYTE
movzx eax, arg
ret
test2 endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
mov al, 255
mov bl, 123
invoke test1, bl
movzx eax, al
print ustr$(eax),13,10
mov al, 255
mov bl, 123
invoke test1, b
movzx eax, al
print ustr$(eax),13,10
mov bl, 123
invoke test2, bl
print ustr$(eax),13,10
inkey "Press any key to exit..."
exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
123
123
123
IMO it's no big deal once you are aware of it, and even when you first encounter it, it's fairly easy to intuit what's happening. But still, if Microsoft went to the trouble to warn about EAX being overwritten when it's used to pass the address of a stack variable, they should have warned about this problem as well.
You might want to follow this, from console colors. restore not working (http://www.masm32.com/board/index.php?topic=8758.msg63746#msg63746)
Quote from: drizz on February 22, 2008, 05:14:12 PM
Quote from: drizz on February 22, 2008, 02:51:41 AMtoo tired to write more right now
Here are some links. In most threads you can find my posts.
http://www.masm32.com/board/index.php?topic=7983.0
http://www.masm32.com/board/index.php?topic=1026.0
http://www.masm32.com/board/index.php?topic=7866.msg57776#msg57776
http://www.asmcommunity.net/board/index.php?topic=25665.0
http://www.asmcommunity.net/board/index.php?topic=22227.0
http://www.asmcommunity.net/board/index.php?topic=19445.0
MichaelW so you're saying the bug is caused if you try and use al as a byte param since eax is used as a scratch register? nothing else is a issue?
I'm simply saying that AL will be unexpectedly changed when it is not apparently involved in the call. I first noticed this in 16-bit code for a byte to decimal conversion macro that was supposed to preserve all registers, but which corrupted AX. If you pass AL, invoke does a PUSH EAX so there is no problem. If you pass some other byte register or an 8-bit memory operand invoke moves it into AL and then does a PUSH EAX. I was wrong about invoke using EAX as a scratch register.
Testing just now, for this procedure and call:
test3 proc arg1:DWORD, arg2:BYTE
print ustr$(arg1),13,10
ret
test3 endp
...
invoke test3, eax, bl
MASM will return "register value overwritten by INVOKE", but if you reverse the order of the parameters it assembles silently.
explain is here
Quote
test1 PROTO :BYTE
mov al, 255
mov bl, 123
invoke test1, bl
movzx eax, al
;------------------------ listing ---------------------------
mov bl, 123
.LISTALL
00000041 A0 00000000 R * mov al, b
00000046 50 * push eax
00000047 E8 0000003C * call test1
0000004C 0F B6 C0 invoke test1, b
movzx eax, al
;--------------------------------------------------------------
This appear with the translate of byte to dword.Masm don't push byte or word in stack
correction:
test1 PROTO :DWORD and no more problem
can't believe this bug has gone through so many masm verisons unrectified.
Hello bug world !
I have tested in my layman manner this so called bug.
It is not a bug. I would call it 'larvae'.
I see it as .LISTALL listlessness and by design could it be ?
I did not a .LISTALL but ran it through OLLYDBG
and it shows, after the call
push ebp
mov ebp, esp
leave
retn 4
actually ToutEnMasm's example is ok :), redefine test1 to "proto :dword" to experience the bug.
test1 proc aa:dword
ret
test1 endp
it will also happen if you use vararg
myprintf proc c fmt:dword, args:vararg
ret
myprintf endp
LOCAL ab:word
int 3
invoke myprintf,edi,bl,ab,123
size override prefix not added by ml
004012A1 6A 7B push 7B
004012A3 6A 00 push 0
004012A5 66:FF75 F2 push word ptr [ebp-E]
004012A9 6A 00 push 0
004012AB 8AC3 mov al, bl
004012AD 66:0FB6C0 movzx ax, al
004012B1 66:50 push ax
004012B3 57 push edi
004012B4 E8 D2FFFFFF call 0040128B
004012B9 83C4 10 add esp, 10
also look how zero extension is silly
this bug is fixed in ml v9.00.30729.01
and the code produced by it:
0040138C 6A 7B push 7B
0040138E 66:6A 00 push 0
00401391 66:FF75 FE push word ptr [ebp-2]
00401395 66:6A 00 push 0
00401398 8AC3 mov al, bl
0040139A 66:0FB6C0 movzx ax, al
0040139E 66:50 push ax
004013A0 57 push edi
004013A1 E8 D7FFFFFF call 0040137D
004013A6 83C4 10 add esp, 10
can you upload ML 9 somewhere please drizz
you can find it in VS2008 Express With SP1, if you don't want to install it ml.exe is in "Ixpvc.exe/vs_setup.cab" SFX (unpackable by 7zip)
ugh I got customers whos I need to contact to get this fixed, im just gonna install this annoying gig sdk in vmware, take out the new ml.exe etc files thats needed and zip up somewhere with download link to the Visual C++ 2008 Redistributable Package. others shouldn't have to go through all this non-sense too just for the new masm.
You can run ml.exe 9.0 without installing the redistributable package. (http://www.masm32.com/board/index.php?topic=9821.0)
Yeah I just saw that guide Vortex, seems to be a lot simpler just to install the package since its tiny.
I replaced the ml and link with the new verisons is compiling ok except when I try
/SECTION:.text,RWX
says invalid argument anyone know how to get it to work?
*update doesn't appear to allow a /section anymore? I replaced new link with the old and it seems to compile fine with the new ml and old link, is there any risk in this?
I rarely see make procedures setting the section characteristics manually in the linking process !
Quote from: E^cube on March 25, 2009, 07:00:29 PM
I replaced the ml and link with the new verisons is compiling ok except when I try
/SECTION:.text,RWX
says invalid argument anyone know how to get it to work?
/SECTION:.text,rw
e