Assume you work with a Type, possibly a full INTEGER TYPE. Like this:
TYPE D_List
U AS LONG ' In Use = %True, Empty=%False
N AS DWORD ' Nr of Elements (0 - Liste ist leer)
D AS DWORD ' actual maximum Dimension
END TYPE
Now you have an Instance of this Type and you want to check it if its zero:
IF M_LC01.D=0 THEN GOSUB L002
Here is what PowerBasic will make out of it.
FILD LONG PTR [0020B144]
MOV EAX, DWORD PTR [0020AB58]
CALL L208D1C
FCOMPP
FNSTSW AX
SAHF
JNZ SHORT L201AA1
Too much Floating Point (FPU) Instruction, just for a Test if zero in an Integer!
Now we make a little change:
REGISTER R01
R01=M_LC01.D
IF R01=0 THEN GOSUB L002
So this way we get what we expect. The smallest and fastest code for a "Zero check".
MOV EAX, DWORD PTR [0020AB58]
MOV ESI, EAX
CMP ESI, BYTE 00
JNZ SHORT L201A96
Just in case your REGISTERS are in use at this time.
Use these Macros:
MACRO Push_Reg
! PUSH EDI
! PUSH ESI
END MACRO
MACRO Pop_Reg
! POP ESI
! POP EDI
END MACRO
As a Sidenote:
In this case, adding () does not influence the optimization.
IF (R01=0) THEN GOSUB L002
Will produce exactly the same ASM-Output.
Hi Theo,
ESI and EDI are 32-bit/DWORD registers that can also be accessed at a 16-bit level via their lower SI/DI WORD "halves". But they cannot be accessed at an 8-bit/BYTE level at all nor is there, to the best of my knowlege, a CMP mnemonic to test 32-bit registers against a 16- or 8-bit immediate value.
So, shouldn't
CMP ESI, BYTE 00
in fact be
CMP ESI, 0
where 0 will be interpreted as DWORD according to the register size?
Then, talking about low level code optimization and assuming ESI is a mere disposable temporary variable, shouldn't we just
OR ESI, ESI
or
AND ESI, ESI
either of which is going to set the zero flag to the same effect if ESI actually is 0, and thus yield a much shorter machine code byte sequence than CMP ESI, 0 where literal 0 alone would occupy 4 bytes?