codes as follows:
------------------------------------------------------------------------------------
  Jmp CodeStart
CRITICALBEGIN:
    HashData1    dd    05d56345ch
    HashData2    dd    ????
    HashData3    dd    ????
    ......
CRITICALEND:
  ......
CodeStart:
    ;assume ESI has pointed to CRITICALEND and (CRITICALEND - CRITICALBEGIN) = 5d
    ;--------------------------------------------------------------------------------
    sub esi, (CRITICALEND - CRITICALBEGIN);      81 ee 5d 00 00 00
    sub esi, low(CRITICALEND - CRITICALBEGIN);  81 ee 5d 00 00 00
    sub esi, byte(CRITICALEND - CRITICALBEGIN); 81 ee 5e(?) 00 00 00
    sub esi, 05dh;                                              83 ee 5d
    ;----------------------------------------------------------------------------------

  question1: only the codes generated by the fourth are what i want, but i don't want to sacrifice the advantage of auto-counting the length of CRITICAL data section by pre-compiler. how can i do it? ( to use 'add esi, (CRITICALBEGIN - CRITICALEND)' also generates 6 bytes)

  question2: why the codes of 'sub esi, byte(CRITICALEND - CRITICALBEGIN)'(the third sub instruction) include a 5e but 5d?

thanks.
Posted on 2005-10-26 20:51:18 by Lava
Just a question, what do you use to assemble your code?
Posted on 2005-10-26 21:23:48 by roticv
Something very old (or very bugged), I guess  :shock:
Posted on 2005-10-26 21:27:04 by ti_mo_n
sorry for my negligence, the assembler is masm :
-------------------------------------------------------------------
D:\>ml
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

usage: ML [ options ] filelist [ /link linkoptions]
Run "ML /help" or "ML /?" for more info
Posted on 2005-10-26 22:28:47 by Lava
Lava,
    The answer to your prob is easy.  You want MASM to generate the shorter 83 BYTE operand code right?  Well, that 83 instruction sign extends the immediate BYTE operand.  You don't want that to happen when your table length is greater than 7 bits, do you?  So MASM has to use the 81 DWORD operand to avoid sign extension.  Now if MASM were really smart, it would know if the byte operand was less than or equal 7 bits and use the 83 BYTE operand code.  Ratch
Posted on 2005-10-26 23:18:04 by Ratch
The reason masm generates long opcodes in that particular cases is because you are subtracting pointers. At assembly stage, MASM is not quite sure what the difference would be, so it is not able to optimize for a shorter opcode. I imagine the actual difference is filled in by the linker.
Posted on 2005-10-26 23:30:15 by comrade

Lava,
     The answer to your prob is easy.  You want MASM to generate the shorter 83 BYTE operand code right?  Well, that 83 instruction sign extends the immediate BYTE operand.  You don't want that to happen when your table length is greater than 7 bits, do you?  So MASM has to use the 81 DWORD operand to avoid sign extension.  Now if MASM were really smart, it would know if the byte operand was less than or equal 7 bits and use the 83 BYTE operand code.  Ratch


------------------------------
thanks.

yes, but what u posted is the reason, not the answer:)

my question is ' is masm smart enough? or how to make it smarter?'

'81 ee 5d 00 00 00' may be executed faster than 83 because of avoiding  sign extension(i guess), but how can i tell the masm: do not care the speed, make it shorter?
Posted on 2005-10-27 02:21:57 by Lava
If you look at Comrade's explanation, then it would make a hell lot of sense why it is not possible to do so. Try FASM instead.
Posted on 2005-10-27 03:58:15 by roticv

If you look at Comrade's explanation, then it would make a hell lot of sense why it is not possible to do so. Try FASM instead.


yes, i got it . that's why i tried 'sub esi, low(CRITICALEND - CRITICALBEGIN), but i am not sure whether the mission is possible.

if the answer is not, i'll try FASM, thank u:)
Posted on 2005-10-27 04:17:28 by Lava
Try this.


    subesi MACRO value
      db 83h,0EEh,value
    ENDM
......
In code,

    subesi CRITICALEND - CRITICALBEGIN
Posted on 2005-10-27 06:19:34 by hutch--
question1 answer:
sub esi,@CatStr(%(CRITICALEND-CRITICALBEGIN))


question2 answer:
"byte" by itself means no size cast, it means +1 in this case
to use size cast use "type ptr"
like for long push 0 :
  push dword ptr 0




Posted on 2005-10-27 08:21:15 by drizz
Lava,


'81 ee 5d 00 00 00' may be executed faster than 83 because of avoiding  sign extension(i guess), but how can i tell the masm: do not care the speed, make it shorter?


     Faster or slower is irrelevant, correctness is not.  You don't want a sign extension to generate a negative number for a table length; which is what you get if the length is equal or greater than 080H.  The following snippet of code appears to work.  You can MACROtize it you choose.  It appears that MASM marks any expression that contains an address label as a 32-bit operand, no matter how hard you try to tell it otherwise.  While not incorrect, the code is not as small as it could be. Ratch


DIFF = (CRITICALEND-CRITICALBEGIN)

.CODE
MAIN:
    IF DIFF LT 080H
     BYTE 081H,0EEH,DIFF
    ELSE
     SUB ESI,DIFF
    ENDIF
Posted on 2005-10-27 10:04:33 by Ratch
It works very well:
    DIFF = (CRITICALEND - CRITICALBEGIN)
    IF DIFF LT 080H
        BYTE 083H, 0EEH, DIFF
    ELSE
        sub esi, DIFF
    ENDIF
-----------------------------------------------------------
hutch, ratch and other guys, thanks.

drizz:
    sub esi, @CatStr(%(CRITICALEND - CRITICALBEGIN)
the result is weird: 83 ee 6d(not 5d). i also try this:
    sub esi, @CatStr(%DIFF)
83 ee 6d appears again, why?

Posted on 2005-10-27 20:02:34 by Lava
Correct me if I am wrong, but I thing drizz's method can't work. The @CatStr directive forces evaluation of the difference too early, when not all of instructions are encoded, and thus the result can't be correct. MASM seems to be undeceivable in this case.
Posted on 2005-10-28 10:07:00 by MazeGen
yes, my mistake, i assumed it was data only (hashdata1..),
if you have relocatable labels(+instructions that use it) in between it wont work.
CRITICALBEGIN1:
jmp @1
@1:
CRITICALEND1:
%echo @CatStr(%(CRITICALEND1-CRITICALBEGIN1))

if you use location counter $ it will work
CRITICALBEGIN2:
jmp $+2
CRITICALEND2:
%echo @CatStr(%(CRITICALEND2-CRITICALBEGIN2))
Posted on 2005-10-28 13:50:21 by drizz
drizz,
  yes, it is data only and the length is 5d. but the code generated by your method is 6d. i have no idea about how masm process that instruction. i think that MASM also get confused.


yes, my mistake, i assumed it was data only (hashdata1..),
if you have relocatable labels(+instructions that use it) in between it wont work.
CRITICALBEGIN1:
jmp @1
@1:
CRITICALEND1:
%echo @CatStr(%(CRITICALEND1-CRITICALBEGIN1))

if you use location counter $ it will work
CRITICALBEGIN2:
jmp $+2
CRITICALEND2:
%echo @CatStr(%(CRITICALEND2-CRITICALBEGIN2))

Posted on 2005-10-29 20:08:17 by Lava
Lava,
that's interesting, could you post all code (data) between CRITICALEND and CRITICALBEGIN?
Posted on 2005-10-30 01:59:47 by MazeGen
drizz and MazeGen:
  sorry, i made a mistake. the CRITICALDATA in the sample is only data, my working code is not. what i tried is the working code.
my working code is just like what drizz said:
  jmp start
  CRITICALBEGIN:
        HashData1 dd ?????
        ......
    CRITICALEND:
  start:
        jmp @F
        ......
  @@:
        .....
  ESIISHERE:
        sub esi, (ESIISHERE - CRITICALBEGIN)
Posted on 2005-10-30 06:55:21 by Lava