Author Topic: Do you work with TYPE's?  (Read 69 times)

0 Members and 1 Guest are viewing this topic.

Offline Theo Gottwald

  • Administrator
  • Hero Member
  • *****
  • Posts: 1114
  • Gender: Male
    • it-berater
Do you work with TYPE's?
« on: May 07, 2018, 11:08:25 AM »
Assume you work with a Type, possibly a full INTEGER TYPE. Like this:

Code: [Select]
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:

Code: [Select]
IF M_LC01.D=0 THEN GOSUB L002
Here is what PowerBasic will make out of it.

Code: [Select]
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:
Code: [Select]
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".

Code: [Select]
        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:

Code: [Select]
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.
Code: [Select]
IF (R01=0) THEN GOSUB L002
Will produce exactly the same ASM-Output.

Offline Mike Lobanovsky

  • Jr. Member
  • **
  • Posts: 72
  • Gender: Male
Re: Do you work with TYPE's?
« Reply #1 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?
Mike
(3.6GHz Intel Core i5 w/ 16GB RAM, 2 x GTX 650Ti w/ 2GB VRAM, Windows 7 Ultimate Sp1)