Powerbasic Museum 2020-B

IT-Berater: Theo Gottwald (IT-Consultant) => Low Level Code Optimization => Low Level Code Optimization PB 10 => Topic started by: Theo Gottwald on May 07, 2018, 11:08:25 AM

Title: Do you work with TYPE's?
Post by: Theo Gottwald on May 07, 2018, 11:08:25 AM
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.
Title: Re: Do you work with TYPE's?
Post by: Mike Lobanovsky on May 07, 2018, 12:53:25 PM
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?