I'm getting assembly errors, but only when I try to assemble a debug version. The output looks like-
F:\masm32\BIN\ML /c /coff /Cp /nologo /Fm /Zi /Zd /Fl /Sn /I"F:\masm32\INCLUDE" "F:\WinAsm\Progs\temp\strcat.asm"
Assembling: F:\WinAsm\Progs\temp\strcat.asm
F:\WinAsm\Progs\temp\strcat.asm(235) : error A2006: undefined symbol : @@
MacroLoop(38): iteration 1: Macro Called From
MacroLoop(69): iteration 1: Macro Called From
MacroLoop(74): iteration 1: Macro Called From
F:\WinAsm\Progs\temp\strcat.asm(235): Main Line Code
F:\WinAsm\Progs\temp\strcat.asm(235) : error A2006: undefined symbol : @@
MacroLoop(46): iteration 1: Macro Called From
MacroLoop(69): iteration 1: Macro Called From
MacroLoop(74): iteration 1: Macro Called From
F:\WinAsm\Progs\temp\strcat.asm(235): Main Line Code
F:\WinAsm\Progs\temp\strcat.asm(235) : error A2006: undefined symbol : @@
MacroLoop(63): iteration 1: Macro Called From
MacroLoop(69): iteration 1: Macro Called From
MacroLoop(74): iteration 1: Macro Called From
F:\WinAsm\Progs\temp\strcat.asm(235): Main Line Code
.
etc. for every loop
works just fine until I put in the /Zd /Zi /Fm options.
This is the file I posted over in the Laboratory/strcat thread http://www.masmforum.com/simple/index.php?topic=2471.0
anyone have any idea what the problem is? I think the code in question is:
%FOR extra,<0,1,2,3>
print chr$(13,10)
print chr$("&extra& byte misalignment",13,10)
%FOR proc,<Procs>
print fld$(chr$("&proc&"),HDRWIDTH)
%FOR T1T2,<Tests>
sep instr 1,<T1T2>,</>
T1 substr <T1T2>,1,sep-1 ; len of string 1
T2 substr <T1T2>,sep+1 ; len of string 2
; create fresh test strings for each routine to use
mov eax,offset String1
add eax,extra ; start of string1 for testing
mov Str1Offset,eax
add eax,T1 ; where zero byte terminator will be
mov Str1ZeroOffset,eax
mov eax,offset String2
add eax,extra ; start of string2 for testing
mov Str2Offset,eax
add eax,T2 ; where zero byte terminator will be
mov Str2ZeroOffset,eax
mov edi,offset String1 ; create test string values
mov ecx,MaxStr*2+48 ; leave 16 bytes at end for accidents
mov al,255
rep stosb
mov eax,Str1ZeroOffset
mov [eax],byte ptr 0 ; set length of string
mov edi,offset String2 ; create test string values
mov ecx,MaxStr+16
mov al,254
rep stosb
mov eax,Str2ZeroOffset
mov [eax],byte ptr 0 ; set length of string
; run twice to verify operation before running a million times
mov eax,Str1ZeroOffset
mov [eax],byte ptr 0 ; reset length of string
invoke proc,Str1Offset,Str2Offset
invoke CheckForError,T1,T2
jnc @f ; ok
print chr$("&proc&",13,10)
jmp QuitTests
@@:
mov eax,Str1ZeroOffset
mov [eax],byte ptr 0 ; reset length of string
invoke proc,Str1Offset,Str2Offset
invoke CheckForError,T1,T2
jnc @f ; ok
print chr$("&proc&",13,10)
jmp QuitTests
@@:
; now do actual time test
counter_begin LoopCount, HIGH_PRIORITY_CLASS
mov eax,Str1ZeroOffset
mov [eax],byte ptr 0 ; reset length of string
invoke proc,Str1Offset,Str2Offset
counter_end
mov ebx,eax
print fld$(sstr$(ebx),COLWIDTH,1)
; and one more check to be sure everything is still ok
mov eax,Str1ZeroOffset
mov [eax],byte ptr 0 ; reset length of string
invoke proc,Str1Offset,Str2Offset
invoke CheckForError,T1,T2
jnc @f ; ok
print chr$("&proc&",13,10)
jmp QuitTests
@@:
ENDM
print chr$(13,10)
ENDM
ENDM
QuitTests:
It hates those jnc @f instructions in debug mode!
Ok, that's way too much code to look at. Here's the minimum to reproduce the error-
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\macros\macros.asm
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.code
align 16
start:
%FOR T1T2,<0,1>
jnc @f ; ok
print chr$(13,10)
@@:
ENDM
exit
end start
and the results of assembling it:
F:\masm32\BIN\ML /c /coff /Cp /nologo /Fm /Zi /Zd /Fl /Sn /I"F:\masm32\INCLUDE" "F:\WinAsm\Progs\temp\strcat.asm"
Assembling: F:\WinAsm\Progs\temp\strcat.asm
F:\WinAsm\Progs\temp\strcat.asm(21) : error A2006: undefined symbol : @@
MacroLoop(1): iteration 1: Macro Called From
F:\WinAsm\Progs\temp\strcat.asm(21): Main Line Code
F:\WinAsm\Progs\temp\strcat.asm(21) : error A2006: undefined symbol : @@
MacroLoop(1): iteration 2: Macro Called From
F:\WinAsm\Progs\temp\strcat.asm(21): Main Line Code
It has something to do with the print macro because it assembles just fine with another command insted.
Ok, later---
It's calling any macro in this condition. This simple code causes the same problem-
.nolist
.486
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\macros\macros.asm
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
soff Macro QuotedText:Vararg ; returns offset to a string
Local LocalText
.data
LocalText db QuotedText,0
.code
EXITM <offset LocalText>
Endm
.code
align 16
start:
%FOR T1T2,<0,1>
jnc @f ; ok
mov eax,soff("x")
@@:
ENDM
exit
end start
Jim,
This is the disassembled output of the macro and code.
start:
jnb lbl0
mov eax, 403000h
lbl0:
jnb lbl1
mov eax, 403002h
lbl1:
push 0
call fn_00401016
This is an OK way to have a look at whether the macro and code are doing what you want with it.
Right. It assembles perfectly in release mode. No problem. The problem is trying to assemble a debug version and getting the errors. I have no idea why I would assemble the exact same code and get an error only using the debug options. My gut feeling says this is a masm bug, but I'm certainly open to suggestions. You can see the exact line from the assembler output-
F:\masm32\BIN\ML /c /coff /Cp /nologo /Fm /Zi /Zd /Fl /Sn /I"F:\masm32\INCLUDE" "F:\WinAsm\Progs\temp\strcat.asm"
Any ideas? Does anybody else get the error? Is it just my machine or software?
Jimg,
I get the same errors when doing a debug assemble on the code you posted. I get the same thing with ML 6.15 and ML 7.10. Not sure why. What is MacroLoop?
QuoteWhat is MacroLoop?
I'm pretty sure masm is considering the for loop a macro. Thanks for testing and verifying the problem, I was really starting to get paranoid.
Jimg,
QuoteI'm pretty sure masm is considering the for loop a macro.
That makes sense.
Jimg,
FWIW, I generated a listing file of your code. I took the expanded code and tried assembling it with debug settings.
The code:
.486
.model flat, stdcall
option casemap :none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.code
start:
jnc @f
.data
szX1 db "x", 0
.code
mov eax, OFFSET szX1
@@:
jnc @f
.data
szX2 db "x", 0
.code
mov eax, OFFSET szX2
@@:
push 0
call ExitProcess
end start
The errors:
Microsoft (R) Macro Assembler Version 7.10.3077
Copyright (C) Microsoft Corporation. All rights reserved.
Assembling: test2.asm
test2.asm(11) : error A2006: undefined symbol : @@
test2.asm(17) : error A2006: undefined symbol : @@
If you change the @@ labels to l1 and l2 it assembles fine. If you change the @@ to l1 in the original code, you get a symbol redefinition error.
Ah, read carefully:
Microsoft Macro Assembler Reference
@@:
Defines a code label recognizable only between label1 and label2, where label1 is either start of code or the previous @@: label, and label2 is either end of code or the next @@: label. See @B and @F.
I'm pretty sure the interspersed .data and .code segments are the culprit.
QuoteI'm pretty sure the interspersed .data and .code segments are the culprit.
I tried that in another test prog and it worked as expected.
The code seems like it should be just as legal in debug mode as release mode, and it assembles in release mode without a problem.
QuoteThe code seems like it should be just as legal in debug mode as release mode...
That's true. So much for my theory. :bg
Greg,
I tested your code as listed and I generated the same errors. When I moved the data into its own .data section, as you suggested, the errors diappeared.
This tells me that your theory is correct. :U
Paul
Paul-
But if it works in release mode and not in debug mode, it's still a bug in masm, right?
And can anybody think of a workaround for the code?
%FOR Test,<0,1>
sub eax,1
jnc @f
print chr$("&Test&",13,10)
@@:
Jimg,
I guess you could call it a soft error. And the workaround is as we have just said, move the data. When I moved the data, the error went away as Greg theorized it would. Did you miss that part of my post? :wink
Paul
The problem is that the data is dynamically created by the print macro based upon what the for loop extracts from the input string. Theoretically, I could figure out what each should be, every time I make a change to the input string, allocate a data string, and figure out some way to get the address of that string based upon what the for loop extracts later on, but that's the whole purpose of loops and macros and all that good masm stuff, so I don't have to do the overhead myself :bg
Does the release version actually execute correctly, or does it just assemble without error?
The release version seems to work perfectly here. I have, of course, now moved on to a different way of doing the code. But it's still a curiosity why the debug version should be having problems.
Jim,
I personally find a debugger about as useful as a hip pocket in a singlet and protected mode Windows does not help much either. For REAL MEN with a lot of money and time to waste, SOFTICE and it current successor is the boss of the block but its primarily used for driver development.
What I personally do with macro code is either expand it and look at the /EP output or disassemble it and look at the opcode generation, both of which are precision ways to test out macro code.
The last debugger I liked was 1990 Microsoft Codeview that came with MASM as I used to write code back then that looked like a debugger listing but those days are long gone and the later ones are poor in comparison and the code is far more complex in a multitasking environment.