Hi,
I have found a strange behavior in masm32, and that happens when using offset subtraction in the parameters passed in an invoke instruction.
For example:
invoke MySub, OFFSET label1 - OFFSET label2
generates different code to:
push OFFSET label1 - OFFSET label2
call MySub
The difference is that the pushed value in the first example is not correctly calculated by masm32. Using equates does not fix the issue.
Am I doing something wrong or is this a bug?
Thank you very much in advance
Hi julioposa2,
Welcome to the forum.
Running the test code below, I cannot see any problem. Would you please post here your code so we can reproduce the issue?
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\msvcrt.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\msvcrt.lib
MySub PROTO :DWORD
.data
label1 db 'abcd',0
label2 db 'efgh',0
message db 'eax = %X',13,10,13,10,0
.data?
.code
start:
invoke MySub,OFFSET label1 - OFFSET label2
push OFFSET label1 - OFFSET label2
call MySub
invoke ExitProcess,0
MySub PROC param:DWORD
invoke crt_printf,ADDR message,param
ret
MySub ENDP
END start
The ouput is :
eax = FFFFFFFB
eax = FFFFFFFB
Hi Vortex, thank you very much for your prompt reply.
I think the issue only happens when referencing labels from inside the code. I was unable to reproduce the problem with your code, but modify it in this way and tell me the results:
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\msvcrt.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\msvcrt.lib
MySub PROTO :DWORD
.data
label1 db 'abcd',0
label2 db 'efgh',0
message db 'eax = %X',13,10,13,10,0
.data?
.code
start:
jmp cls
cls:
invoke MySub,OFFSET cls - OFFSET start
push OFFSET cls - OFFSET start
call MySub
invoke ExitProcess,0
MySub PROC param:DWORD
;invoke crt_printf,ADDR message,param
ret
MySub ENDP
END start
The value pushed in the invoke sentence is 0Ah, while the value pushed in the manual push sentence is 2.
Best regards
Appears to be a phase error between passes in MASM 6.15
MASM 10.00 doesn't even like your syntax, prefering
mov eax,OFFSET cls - OFFSET start
invoke MySub,eax
Thank you, I thought I was getting mad :P
What masm version do you refer to? I download from this page the masm32 package version 10 and the ml assembler that comes within it is version 6.14.8444
Regards
I typically use MASM 6.15 for most general 16 and 32-bit code, I'd probably use something else for SSE2,3,4 code.
Microsoft (R) Macro Assembler Version 6.15.8803
Microsoft (R) Macro Assembler Version 10.00.30319.01
Thanks.
I though the v10 package from the main page contained all components up to date. Why is the 6.14 version still packaged in it?
Is the latest version publicly available anywhere?
Thanks
Quote from: julioposa2
I though the v10 package from the main page contained all components up to date. Why is the 6.14 version still packaged in it?
Is the latest version publicly available anywhere?
Probably licencing issues, I bought my earlier versions. Plus the new version probably breaks some of the older libraries or macros. All the MASM 6.1x versions are quite serviceable.
Microsoft has MASM 10.00 posted on their website for download, perhaps with another package. Try Google or Bing?
Hi julioposa2,
I use the same version 6.14.8444
Confirmed that the same issue happens in ml version "6.15.8803".
Tested also in 8.x and 10.x and ml refuses to assemble those instructions as commented by Clive.
Vortex, do you reproduce the issue with the offsets in the code section as I suggested before?
Thanks
It's clearly a Masm v6 bug. It happens when a jump instruction is between the two code labels.
Masm v8+ is better, because at least it complains and doesn't silently produce wrong code. As for the PUSH, there exists a workaround for Masm v8:
PUSHD label2 - label1 ;using PUSHD makes Masm v8 accept the expression
Hi julioposa2 ,
I can reproduce the issue. Here is the result :
eax = A
eax = 2
Quote from: julioposa2 on September 08, 2010, 01:45:07 PM
Hi Vortex, thank you very much for your prompt reply.
I think the issue only happens when referencing labels from inside the code. I was unable to reproduce the problem with your code, but modify it in this way and tell me the results:
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\msvcrt.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\msvcrt.lib
MySub PROTO :DWORD
.data
label1 db 'abcd',0
label2 db 'efgh',0
message db 'eax = %X',13,10,13,10,0
.data?
.code
start:
jmp cls
cls:
invoke MySub,OFFSET cls - OFFSET start
push OFFSET cls - OFFSET start
call MySub
invoke ExitProcess,0
MySub PROC param:DWORD
;invoke crt_printf,ADDR message,param
ret
MySub ENDP
END start
The value pushed in the invoke sentence is 0Ah, while the value pushed in the manual push sentence is 2.
Best regards
You are using two different segment declarations: ".code" and ".data". MASM/TASM will take such declarations very seriously.
Try to put constants into the ".code" segment.
Quote from: TASMUser on September 08, 2010, 09:04:33 PM
You are using two different segment declarations: ".code" and ".data". MASM/TASM will take such declarations very seriously.
True. However, nobody did claim that Masm/Tasm will ignore those declarations. Anyway, it's off-topic, because the two labels are in the very same segment.
Quote from: TASMUser on September 08, 2010, 09:04:33 PM
Try to put constants into the ".code" segment.
The labels (="relocatable constants") are in the .code segment already.
Poasm Version 6.00.4 creates the correct code :
eax = 2
eax = 2
Thank you for all your replies.
I'm a bit disappointed with MASM.
I started in the ASM world in the old 16 bits DOS years, using TASM, but when Windows and the 32 bits came I complete lost track because I hadn't enough time for this hobby. Now I want to catch up the 32 and 64 bits asm world and I though that MASM was a good assembler to stick to, but from what I have read, the 64 bits support is very limited.
I'm now discovering that there are many other alternatives (JWASM, GoASM, PoASM, NASM, etc), but I don't know with one to pick up. As I'm almost starting up I don't mind choosing an assembler with different directives and nomenclature (as NASM), but I'm a bit lost.
Could you please recommend me one with good support? HLL and support for other platforms like LLC would be desirable.
Thank you very much.
Hi julioposa2,
I would strongly recommend Jwasm. Japheth is maintaining the tool and it's a Masm compatible assembler. It supports 16,32 and 64-bit programming.
Another alternative is Pelle's Poasm. It's nearly a Masm compatible assembler but there are some differences concerning macros.
Hello,
Quote
invoke MySub, OFFSET label1 - OFFSET label2
There is only one solution if this expression don't work.The linker reallocate this labels at compile time and you have to use the lea instruction instead of offset.