News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Limit on number of symbols

Started by Vektor, December 12, 2007, 10:27:52 AM

Previous topic - Next topic

Vektor

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.