Here is another solution that uses shifts, but I think it is βcleanerβ (although not as clean as David's suggestion):
result := MSB; result := (result shl 8) or b2; { could use "shl sizeof(b2)" instead of 8 } result := (result shl 8) or b3; etc result := (result shl 8) or b8;
this solution avoids all βmagicβ shifting values, and is probably easier to understand. Furthermore, if MSB..b8 (or b1..b8) was an array of bytes, the above code could easily be converted into a single linear loop.
To answer the question of why the compiler does not accept a value of 40 or higher, the reason is most likely related to this quote from volume 2B of the Intel instruction set reference for the SHLD instruction:
In non-64-bit modes and the default is 64-bit mode; only bits 0 through 4 of the count. This masks the counter to a value from 0 to 31. If count is larger than the operand size, the result is undefined.
The equivalent condition in the SHL instruction is not so strict:
8086 does not mask shift count. However, all other IA-32 processors (starting with Intel 286) make a shift counting mask of up to 5 bits, which leads to a maximum count of 31. This masking is performed in all operating modes (including virtual-8086) to reduce the maximum execution time of the instruction.
In any case, a value greater than 31 is either useless (when using SHL) or undefined (when using SHLD). The compiler obviously knows about this, and this prevents you from writing code that is potentially erroneous (in 64-bit mode).
if you are really doing this 50 MLRL operation. times, then you might want to do this in an inline assembly, which would be pretty simple:
asm xor eax, eax or eax, MSB { or b1 depending on how you named the MSB } shl eax, 8 or eax, b2 shl eax, 8 or eax, b3 shl eax, 8 or eax, b4 mov High32bit, eax end;
and repeat the above operation for the low-order 32-bit word and b5th in figure eight. I did not suggest using SHLD because I do not believe that Delphi supports 64-bit registers or 64-bit instructions (I could be wrong, I never tried).
Note. I heard rumors that the 64-bit version of Delphi does not support built-in assembly. It may or may not be, but I would stay away from the built-in assembly if it is really absolutely necessary.
Hope this helps,
John.
PS: there is another reason why David Heffernan's decision is the best. In the solution I presented, each instruction depends on the previous instruction (that is, eax must be shifted by 8 to the next "or" command can be executed). David's solution sets individual bytes, as such, each assignment does not depend on the previous assignment, this will allow the processor to potentially perform several assignments in parallel. In this era of multi-core processors, it can be a little faster than the build code I gave as an example.