NO

Author Topic: Frightening Code -- read your CPU flags register :-)  (Read 3589 times)

Rainbow Sally

  • Guest
Frightening Code -- read your CPU flags register :-)
« on: January 30, 2005, 02:27:59 am »
Whether or not this is useful is another question.  But it might be interesting to see how various operations affect the flags and if you read them soon enough after an operation, the results appear to be reliable enough to be, at a minimum, educational.

See the warning below before you decide whether or not to use this technique in a serious code project.

Code: [Select]

// cpuflags.c

///////////////////////////////////////////////////////////////
// Detect a carry during the last operation

#define CYFLG cyflg()

__declspec(naked)
int cyflg(void)
{
        __asm sbb eax, eax
        __asm neg eax   // not necessary, but..
        __asm ret
}


///////////////////////////////////////////////////////////////
// Detect a zero result for last operation

#define ZFLG zflg()

__declspec(naked)
int zflg(void)
{
        __asm mov eax, 1 \
        __asm jz short zflg1 \
        __asm dec eax  \
        __asm zflg1: ret
}


///////////////////////////////////////////////////////////////
// Detect any sign change during last operation

#define OVFLG ovflg()

__declspec(naked)
int ovflg(void)
{
        __asm mov eax, 0 \
        __asm jno short oflg1 \
        __asm inc eax  \
        __asm oflg1: ret
}


///////////////////////////////////////////////////////////////
// Detect the sign of the result of last operation

#define SFLG sflg()

__declspec(naked)
int sflg(void)
{
        __asm mov eax, 0 \
        __asm jns short sflg1 \
        __asm inc eax  \
        __asm sflg1: ret
}



///////////////////////////////////////////////////////////////
// Detect madness and unsafe programming practices with Pelles
// excellent C compiler.  :-)  Truly, a word of warning here:
// This is only for integer math and even then, you had better
// be sure of what the compiler is doing any time you use these
// functions.  Any editing of the code could throw everything
// out of whack.  But (especially if I figure out how to inline
// them) these macros might save you some time -- or maybe just
// some code space -- in a lib or someplace where the code is
// not likely to ever change.
//
// Other than that, you might just enjoy reaching a bit further
// down into your machine and peeking at the flags.  In any case
// it's yours for the taking.
//                                              -Rainbow Sally
///////////////////////////////////////////////////////////////
// test code

#include <stdio.h>
int main(void)
{
    int a = 2;
    int b = 1;
    int c;
    c = a - b;
    if(CYFLG) printf("1: did CYFLG wrong\n");
    c = b - a;
    if(CYFLG) printf("2: did CYFLG right\n");
    c = a - a;
    if(CYFLG) printf("3: did CYFLG wrong\n");
    c = b - b;
    if(!ZFLG) printf("4: did ZFLG wrong\n");
    c = b - b;
    if(ZFLG) printf("5: did ZFLG right\n");
    c = a - b;
    if(ZFLG) printf("6: did ZFLG wrong\n");
    c = a - b;
    if(!ZFLG) printf("7: did ZFLG right\n");
    a = 0x7fffffff;
    a = a + 1;
    if(OVFLG) printf("8: did OVFLG right\n");
    a = a + 1;
    if(OVFLG) printf("9: did OVFLG wrong\n");
    a = a - 2;
    if(OVFLG) printf("10: did OVFLG right\n");
    a = -1;
    if(SFLG) printf("11: did SFLG right\n");
    a = -a;
    if(SFLG) printf("12: did SFLG wrong\n");
    a = -a;
    if(SFLG) printf("13: did SFLG right\n");

    printf("\n numbers 2 5 7 8 10 11 13 <--<< should all be good\n");

    return 0;
}