Hi,
the following small prog compiles and linkes without errors:
but the generated code crashes. If the "nop" line in proc WinMain is activated, the prog runs ok.
the generated listing file is very interesting. Heres an excerpt:
Have a look at eip 00000024. Here masm calculates wrong as eip of next line is 00000023.
Problem seems to be the use of macro CStr, but only if it is used in the first line of a proc (and the error becomes visible only in the next proc?!?)
Has anyone had a similar problem? Or could anyone explain what is wrong?
japheth
the following small prog compiles and linkes without errors:
.386
.Model flat,stdcall
option casemap:none
.nolist
.nocref
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
.list
.cref
CStr macro y:req
local sym
CONST segment dword public 'DATA'
ifidni <y>,<"">
sym db 0
else
sym db y,0
endif
CONST ends
exitm <offset sym>
endm
.data
szDef db "default",0
.code
DisplayLine proto :ptr byte
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,lpszCmdLine:ptr byte,iCmdShow:sdword
local var1:dword
; nop ; program executes ok if activated
mov eax,CStr("Hello")
invoke DisplayLine,eax
xor eax,eax
ret
WinMain endp
DisplayLine PROC pString:ptr byte
local var1:dword
mov eax,pString
.IF (eax == 0)
mov eax,offset szDef
.ENDIF
invoke MessageBox,0,eax,0,MB_OK
ret
DisplayLine ENDP
WinMainCRTStartup proc
invoke GetModuleHandle,0
invoke WinMain,eax,0,0,0
invoke ExitProcess,eax
ret
WinMainCRTStartup endp
end
but the generated code crashes. If the "nop" line in proc WinMain is activated, the prog runs ok.
the generated listing file is very interesting. Heres an excerpt:
00000000 WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,lpszCmdLine:ptr byte,iCmdShow:sdword
local var1:dword
; nop ; program executes ok if activated
00000000 55 * push ebp
00000001 8B EC * mov ebp, esp
00000003 83 C4 FC * add esp, 0FFFFFFFCh
00000000 1 CONST segment dword public 'DATA'
00000000 48 65 6C 6C 6F 1 ??0019 db "Hello",0
00
00000006 1 CONST ends
00000006 B8 00000000 R mov eax,CStr("Hello")
invoke DisplayLine,eax
0000000B 50 * push eax
0000000C E8 00000000 * call DisplayLine
00000011 33 C0 xor eax,eax
ret
00000013 C9 * leave
00000014 C2 0010 * ret 00010h
00000017 WinMain endp
00000017 DisplayLine PROC pString:ptr byte
local var1:dword
00000017 55 * push ebp
00000018 8B EC * mov ebp, esp
0000001A 83 C4 FC * add esp, 0FFFFFFFCh
0000001D 8B 45 08 mov eax,pString
.IF (eax == 0)
00000020 0B C0 * or eax, eax
00000022 75 FF * jne @C0001
00000024 B8 00000000 R mov eax,offset szDef
.ENDIF
00000023 *@C0001:
invoke MessageBox,0,eax,0,MB_OK
00000023 6A 00 * push +000000000h
00000025 6A 00 * push +000000000h
00000027 50 * push eax
00000028 6A 00 * push +000000000h
0000002A FF 15 00000000 E * call _imp__MessageBoxA@16
ret
Have a look at eip 00000024. Here masm calculates wrong as eip of next line is 00000023.
Problem seems to be the use of macro CStr, but only if it is used in the first line of a proc (and the error becomes visible only in the next proc?!?)
Has anyone had a similar problem? Or could anyone explain what is wrong?
japheth
If you put a label instead of nop it also works OK. :confused:
Correct me if I am wrong but there is no indicator to the assembler where the program starts and stops.
Would it work if you used "Start:" and "End Start" ?
Regards,
hutch@movsd.com
Would it work if you used "Start:" and "End Start" ?
Regards,
hutch@movsd.com
Hutch, if /ENTRY is not specified and you don't give a start address
to END, the linker looks for a few predefined symbols, like
WinMainCRTStartup .
to END, the linker looks for a few predefined symbols, like
WinMainCRTStartup .
This sounds like a MASM bug. Any instruction that you put after "local var1:DWORD" makes the program works perfectly. Replace nop with anything you want and it will work
Yup, it sure looks like a MASM bug to me. I just tried assembling it with 6.15 and got the same result.
I think it may have something to do with the CONST section in the macro coming right afrer a LOCAL, but the gererated code does look OK there.
The address of @C0001 should be 000029, 6 bytes more than it is, which also happens to be the size of the CONST section. So it sounds like the "internal pointer" in MASM got screwed up some how. Congratulations! :grin:
I guess the good news is that you know how to fix it. :)
I think it may have something to do with the CONST section in the macro coming right afrer a LOCAL, but the gererated code does look OK there.
The address of @C0001 should be 000029, 6 bytes more than it is, which also happens to be the size of the CONST section. So it sounds like the "internal pointer" in MASM got screwed up some how. Congratulations! :grin:
I guess the good news is that you know how to fix it. :)
Naaaa...
Its just his funny code. :)
I comment out and replaced these two lines and all works well...
I cant say i know where one learns that form (seen others use simular stuff), but .data and .code always worked for me... and seems to be winning the race at this point :)
Hope this helps..
:alright:
NaN
Its just his funny code. :)
I comment out and replaced these two lines and all works well...
;CONST segment dword public 'DATA'
.data
...
;CONST ends
.code
I cant say i know where one learns that form (seen others use simular stuff), but .data and .code always worked for me... and seems to be winning the race at this point :)
Hope this helps..
:alright:
NaN
NaN,
you are right, it works when using the predefined segment directives. But it still is a bug. BTW, I have deliberately used the old style directive so the macro can also be used to define string pointers in the .data section.
japheth
you are right, it works when using the predefined segment directives. But it still is a bug. BTW, I have deliberately used the old style directive so the macro can also be used to define string pointers in the .data section.
japheth
to define string pointers in the any section you can use this macro.
Works fine in your code.
$TO MACRO sText
; $TO defines text both in .data or .code sections and returns its offset
local szText, SegName
SegName TEXTEQU @CurSeg
.data
IF @SizeStr(<sText>) NE 0
szText db sText, 0
ELSE
szText db 0
ENDIF
@CurSeg ENDS
SegName SEGMENT
EXITM <offset szText>
ENDM
Works fine in your code.
Four-F, great :) . Didnt know that predefined @CurSeg "macro".