In one of my projects i have reached the default limit on number of symbols. If i add a few more lines of code, i get this:
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Assembling: HeXHub.asm
tzari.h(973) : error A2005: symbol redefinition : @C0001
tzari.h(973) : error A2005: symbol redefinition : @C0005
tzari.h(974) : error A2005: symbol redefinition : @C0003
tzari.h(975) : error A2005: symbol redefinition : @C0008
tzari.h(975) : error A2005: symbol redefinition : @C0007
tzari.h(980) : error A2005: symbol redefinition : @C000B
tzari.h(987) : error A2005: symbol redefinition : @C000D
tzari.h(987) : error A2005: symbol redefinition : @C0010
tzari.h(989) : error A2005: symbol redefinition : @C0017
tzari.h(993) : error A2005: symbol redefinition : @C001A
tzari.h(996) : error A2005: symbol redefinition : @C0018
tzari.h(996) : error A2005: symbol redefinition : @C001C
tzari.h(1001) : error A2005: symbol redefinition : @C001D
tzari.h(1005) : error A2005: symbol redefinition : @C0024
tzari.h(1008) : error A2005: symbol redefinition : @C002A
tzari.h(1008) : error A2005: symbol redefinition : @C0028
tzari.h(1008) : error A2005: symbol redefinition : @C0026
tzari.h(1009) : error A2005: symbol redefinition : @C0023
tzari.h(1011) : error A2005: symbol redefinition : @C0034
tzari.h(1011) : error A2005: symbol redefinition : @C0032
tzari.h(1011) : error A2005: symbol redefinition : @C0031
tzari.h(1015) : error A2005: symbol redefinition : @C0038
tzari.h(1015) : error A2005: symbol redefinition : @C003B
tzari.h(1015) : error A2005: symbol redefinition : @C003A
tzari.h(1020) : error A2005: symbol redefinition : @C0036
tzari.h(1021) : error A2005: symbol redefinition : @C002B
tzari.h(1026) : error A2005: symbol redefinition : @C0041
tzari.h(1032) : error A2005: symbol redefinition : @C0042
tzari.h(1032) : error A2005: symbol redefinition : @C0044
tzari.h(1035) : error A2005: symbol redefinition : @C0045
tzari.h(1036) : error A2005: symbol redefinition : @C0011
tzari.h(1036) : error A2005: symbol redefinition : @C004C
tzari.h(1036) : error A2005: symbol redefinition : @C004B
tzari.h(1046) : error A2005: symbol redefinition : @C004E
tzari.h(1059) : error A2005: symbol redefinition : @C0050
So i have to move some procedures to libraries to be able to add more code to the main project. This is not a real solution, but so far it works.
Is there a way to adjust this limit on number of symbols ?
hi
the only practical solution is to use global symbols (and reuse them) and not local ones, since the last are not removed from the internal database.
regards,
biterider
I'm thinking exist more one, it to suppose that this names not appear in program it could be system fault. On me experience ml could give such on file not less then 2500 lines, so maybe try to reinstall everything.
The problem is not the system nor the number of lines of code.
For example, i can add these as many as i want:
inc eax
But i can add only a few more of these (less than 100):
.if eax
inc eax
.endif
So far the only way i found to resolve those errors was to move other procedures to libraries (doesn't care which ones i move).
Just such done - 15000 times worked :Â Â :wink
  REPT 15000
  MOV  EAX, 1
  .IF EAX
    INC  EAX
    PRINT sCommandLine
  .ENDIF
  ENDM
If I remember correctly the limit is 32k of symbols. I found this limit in a test piece years ago and the only solution is to split the source file up into smaller parts as each source file that is seperately assembled has the same limit.
The limit seems to be different for different types of symbols. If I create a source file that contains a million code labels:
jmp L1
L1:
jmp L2
L2:
…
Then the file assembles OK (eventually). If I create a source file that contains repeated IF blocks:
.if eax
 inc eax
.endif
MASM assigns code labels @C0001, @C0003, @C0005, etc, up to @C7FFF, and then it starts over at @C0001. So 16384 blocks assemble OK, and then the symbol redefinition errors start with next block.
If I forgo the high-level syntax and use something like this:
or eax, eax
jz L1
 inc eax
L1:
Or eax, eax
jz L2
 inc eax
L2:
…
Then a source with one million blocks assembles OK (eventually). So based on this I think one (difficult) solution would be to replace the .IF directives with macros that had a wider range of symbols available, taking the pressure off of the limited symbol set that the .IF directives share with the .WHILE, .REPEAT, and similar directives.
How's you detailed unfixed ml, simple amazing. I have such macros (recorded sometime and attached now - only comments russian), but that was on ml 5.0 and now I even not sopposed that be need to somebody. I'm view only 80 labels in you first listing, so maybe it's better to check again corruption of all disk files, it maybe and in distributive than go back on twenty years in programming.
[attachment deleted by admin]
Quote from: hutch-- on December 14, 2007, 01:29:37 AM
I found this limit in a test piece years ago and the only solution is to split the source file up into smaller parts as each source file that is seperately assembled has the same limit.
I was looking for a better solution, like something i missed or misunderstood while reading the documentation. I prefer to do something usefull instead of rewriting everything just to compensate a compiler limitation.
Quote from: MichaelW on December 14, 2007, 09:45:56 AM
MASM assigns code labels @C0001, @C0003, @C0005, etc, up to @C7FFF, and then it starts over at @C0001. So 16384 blocks assemble OK, and then the symbol redefinition errors start with next block.
You're right, MASM does this for some macros like .if, .while and .repeat, the limit is 32767 (7FFF).
[code removed because of license limitations]
Offtopic: Adamanteus you're joking, right ?
Quote from: Adamanteus on December 12, 2007, 06:16:11 PM
it could be system fault. On me experience ... maybe try to reinstall everything.
Quote from: Adamanteus on December 14, 2007, 07:58:33 PM
I'm view only 80 labels in you first listing, so maybe it's better to check again corruption of all disk files
Yes, you should do that. The following quotes may look the same to you (because of data corruption, of course :bg) but to others they don't:
Quote from: Vektor on December 12, 2007, 10:27:52 AM
Microsoft (R) Macro Assembler Version 6.14.8444
Quote from: Adamanteus on December 14, 2007, 07:58:33 PM
but that was on ml 5.0 and now I even not sopposed that be need to somebody.
QuoteYou're right, MASM does this for some macros like .if, .while and .repeat, the limit is 32767 (7FFF). I was reading the license i found no restrictions related to disassembling or applying patches to ml.exe so i assume posting a patch for ml.exe does not break this forum's rules (if i'm wrong, delete this post).
You are reading the MASM32 license, not the Microsoft license for the DDK components that are distributed with the MASM32 project. The license for those should be in \masm32\licence.
Quote
You may not reverse-engineer, decompile, or disassemble the SOFTWARE PRODUCT, except and only to the extent that such activity is expressly permitted by applicable law notwithstanding this limitation.
QuoteSo 16384 blocks assemble OK
- he counted one result, but get another experementaly ! About what it's saying ? :boohoo:
In my results, which tested only the .IF directive, there is the question of what happened to the even-numbered labels. In the post at the top of this thread there are some even-numbered labels, so there must be some circumstances under which MASM generates them.
That was before moving a full procedure in a library. The procedure has many .if/.else/.endif/.while/ etc.
Microsoft (R) Macro Assembler Version 6.14.8444 Â Â 12/15/07 12:45:30
test.asm    Page 1 - 1
.386
.model flat,stdcall
option casemap:none
00000000 .data
00000000 .data?
00000000 .code
00000000 start:
.if eax
00000000Â 0B C0 Â Â * Â Â or eax, eax
00000002 74 01   *   je   @C0001
00000004 Â Â *@C0002:
00000004Â 40 inc eax
.endif
00000005 Â Â *@C0001:
.if eax
00000005Â 0B C0 Â Â * Â Â or eax, eax
00000007 74 03   *   je   @C0003
00000009 Â Â *@C0004:
00000009Â 40 inc eax
.else
0000000A EB 01   *   jmp  @C0005
0000000C Â Â *@C0003:
0000000CÂ 48 dec eax
.endif
0000000D Â Â *@C0005:
0000000DÂ C3 ret
end start
Microsoft (R) Macro Assembler Version 6.14.8444 Â Â 12/15/07 12:45:30
test.asm    Symbols 2 - 1
Some labels are useless.
And this even useless, labels of 16384 quantity that is MASM limit ?
Guys,
The answer is very simple, I had to do the research years ago for an automated code generator that was capable of producing hundreds of thousands of branches and when I tested the first version using the block .IF notation I found the 32k limit.
I converted the code design to direct mnemonics using jumps and labels and it easily handles much larger branch counts.
Sorry for my late response but i've been busy with other things.
I finally solved my problem. To handle the restriction on number of symbols, one of the following can be done:
- Replacing all high level macros with their asm equivalents is the safest way to handle this error. However, there are 2 main disadvantages: i have to rewrite everything and all high level macros will be gone, the code will be even less understandable for others who read it (unless i add comments and update all comments with every change in any procedure so i have to write same thing twice).
- Moving procedures in libraries - this is what i've done so far but i don't have many procedures to move until i have to rewrite the new ones that will be moved - this works with procedures that don't call other procedures that are not moved yet, and in my project there are not many of them left.
- While studying the way ml.exe handles symbols, i found out that it keeps a 16 bit counter for labels. There are a few macros (.if / .else / .break .if / .continue .if / etc.) for which it generates more labels than needed.
00000000 start:
.if eax
00000000 0B C0 * or eax, eax
00000002 74 01 * je @C0001
00000004 40 inc eax
.endif
00000005 *@C0001:
.if eax
00000005 0B C0 * or eax, eax
00000007 74 03 * je @C0003
00000009 40 inc eax
.else
0000000A EB 01 * jmp @C0005
0000000C *@C0003:
0000000C 48 dec eax
.endif
0000000D *@C0005:
As MichaelW noticed, while assembling a simple list of .if macros, even-numbered labels are generated but not shown. The fact is that ml uses bit15 from that 16 bit counter as a "visibility flag", if it is not set, the label will not be shown in listing. Bit 15 is reset only when an extra unnecessarry label is generated to hide it. Like MS always does - they don't correct the errors, they hide them.
So, another way to handle this error is to use that bit 15 that hides labels as an extension to the 15-bit counter. This can be done with a patch in ml.exe (as i've seen, the license for ml.exe doesn't disallow random byte changes in it and this is a bugfix not a crack anyway):
.04016E9: 80 00
.0401733: 80 00
.0401D74: 80 00
.0401D82: 7F FF
.040202D: 7C 00
.0402037: 7F FF
After patching, you'll notice that all labels will be shown in listing.
00000000 .code
00000000 start:
.if eax
00000000 0B C0 * or eax, eax
00000002 74 01 * je @C0001
00000004 *@C0002:
00000004 40 inc eax
.endif
00000005 *@C0001:
.if eax
00000005 0B C0 * or eax, eax
00000007 74 03 * je @C0003
00000009 *@C0004:
00000009 40 inc eax
.else
0000000A EB 01 * jmp @C0005
0000000C *@C0003:
0000000C 48 dec eax
.endif
0000000D *@C0005:
- There can be done a few patches to correct ml so it won't generate the unneeded labels, but it extends the number of available labels to only a few more. Instead of doing that i prefer to optimize my own code :P
- A 16-bit counter is also not a real solution, this limit can also be easily reached. To extend the counter from 16 to 32 bit the following patch can be applied (after applying the 15 to 16 extension patch, of course):
00001D75: 66 90
00001D79: 25 90
00001D7A: FF 90
00001D7B: FF 90
00001D7C: 00 90
00001D7D: 00 90
00001D8A: 82 D2
00001D8B: 47 F2
00001D8C: 01 03
00001FE7: 66 90
00001FEE: 66 90
00001FF0: 66 90
00001FF7: 66 90
00002025: 66 90
0000202E: 25 90
0000202F: FF 90
00002030: FF 90
00002031: 00 90
00002032: 00 90
00002041: CB 1B
00002042: 44 F0
00002043: 01 03
00041060: 00 57
00041061: 00 51
00041062: 00 8B
00041063: 00 7C
00041064: 00 24
00041065: 00 0C
00041066: 00 8B
00041067: 00 44
00041068: 00 24
00041069: 00 10
0004106A: 00 52
0004106B: 00 B9
0004106C: 00 04
00041070: 00 E8
00041071: 00 06
00041075: 00 E2
00041076: 00 F9
00041077: 00 EB
00041078: 00 1C
00041079: 00 5F
0004107A: 00 C3
0004107B: 00 51
0004107C: 00 B9
0004107D: 00 34
00041081: 00 33
00041082: 00 D2
00041083: 00 F7
00041084: 00 F1
00041085: 00 80
00041086: 00 C2
00041087: 00 41
00041088: 00 80
00041089: 00 FA
0004108A: 00 5B
0004108B: 00 72
0004108C: 00 03
0004108D: 00 80
0004108E: 00 C2
0004108F: 00 06
00041090: 00 88
00041091: 00 17
00041092: 00 47
00041093: 00 59
00041094: 00 C3
00041095: 00 5A
00041096: 00 59
00041097: 00 B0
00041099: 00 90
0004109A: 00 8B
0004109B: 00 C7
0004109C: 00 5F
0004109D: 00 C2
0004109E: 00 10
This patch will also change the way generated labels are named - they no longer have hexadecimal names but literal names. So this is not really a 32-bit extension because of the reduced character set, but it is enough for everyone.
00000000 start:
.if eax
00000000 0B C0 * or eax, eax
00000002 74 01 * je @CBAAA
00000004 *@CCAAA:
00000004 40 inc eax
.endif
00000005 *@CBAAA:
.if eax
00000005 0B C0 * or eax, eax
00000007 74 03 * je @CDAAA
00000009 *@CEAAA:
00000009 40 inc eax
.else
0000000A EB 01 * jmp @CFAAA
0000000C *@CDAAA:
0000000C 48 dec eax
.endif
0000000D *@CFAAA:
A big list of .if macros will look like this:
00000000 .code
00000000 start:
.if eax
00000000 0B C0 * or eax, eax
00000002 74 01 * je @CBAAA
00000004 *@CCAAA:
00000004 40 inc eax
.endif
00000005 *@CBAAA:
.if eax
00000005 0B C0 * or eax, eax
00000007 74 01 * je @CDAAA
00000009 *@CEAAA:
00000009 40 inc eax
.endif
0000000A *@CDAAA:
.if eax
0000000A 0B C0 * or eax, eax
0000000C 74 01 * je @CFAAA
0000000E *@CGAAA:
0000000E 40 inc eax
.endif
0000000F *@CFAAA:
.if eax
0000000F 0B C0 * or eax, eax
00000011 74 01 * je @CHAAA
00000013 *@CIAAA:
...
000A0135 *@CgzsB:
000A0135 40 .if eax
inc eax
000A0136 *@CfzsB:
.endif
000A0136 0B C0 * or eax, eax
000A0138 74 01 * je @ChzsB
000A013A *@CizsB:
000A013A 40 .if eax
inc eax
000A013B *@ChzsB:
.endif
000A013B 0B C0 * or eax, eax
000A013D 74 01 * je @CjzsB
000A013F *@CkzsB:
000A013F 40 .if eax
inc eax
000A0140 *@CjzsB:
...
Anyway, thanks for your replies and suggestions.