Results 1 to 13 of 13

Thread: Circular Bitwise Shifting

  1. #1
    wossname
    Guest

    Circular Bitwise Shifting

    Hi, does anyone know of a library that contains an operator that lets you do CIRCULAR left and right shifts on 4 byte unsigned integers?

    Or failing that, does anyone have the C++ source code for the formula?

    I'm not talking about the normal << shift either.

    Please help, I've got to come up with this by next week!

  2. #2
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Your wish is my command
    Code:
    #include <iostream>
    using namespace std;
    
    unsigned long ROL(unsigned long ulVal, unsigned char count) {
    	__asm {
    		mov eax, ulVal
    		mov cl, count
    		rol eax, cl
    	}
    }
    
    unsigned long ROR(unsigned long ulVal, unsigned char count) {
    	__asm {
    		mov eax, ulVal
    		mov cl, count
    		ror eax, cl
    	}
    }
    
    void main() {
    	cout << hex << 0xAABBCCDD << " " << ROL(0xAABBCCDD, 8) << endl;
    	cout << hex << 0xAABBCCDD << " " << ROR(0xAABBCCDD, 8) << endl;
    }
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  3. #3
    wossname
    Guest
    Thanks Parksie, looks promising, other than one flaw...

    Parse Error before "{"

    on both lines containing "__asm". I'm using the DOS DJGPP ANSI compiler.

    The keyword __asm is being recognised, I can tell this because the text
    goes white. Does it compile in your compiler?

    Hope you can give me a fix for this.

    Anyway I've got a new question too:

    How can I find out the length of a file in bytes?

  4. #4
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    I'm no genius but you could open the file and read until an error or until it's end... and I think Parksie wrote that code for MSVC++ because the other compilers use asm not __asm.
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  5. #5
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    I think GCC might use either asm or __asm__ - I've definitely seen that last one somewhere. Check the compiler documentation. And yes, it compiles like that in VC++ and works.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  6. #6
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    From MSDN:
    Code:
    /* STAT.C: This program uses the _stat function to
     * report information about the file named STAT.C.
     */
    
    #include <time.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdio.h>
    
    void main( void )
    {
       struct _stat buf;
       int result;
       char buffer[] = "A line to output";
    
       /* Get data associated with "stat.c": */
       result = _stat( "stat.c", &buf );
    
       /* Check if statistics are valid: */
       if( result != 0 )
          perror( "Problem getting information" );
       else
       {
          /* Output some of the statistics: */
          printf( "File size     : %ld\n", buf.st_size );
          printf( "Drive         : %c:\n", buf.st_dev + 'A' );
          printf( "Time modified : %s", ctime( &buf.st_atime ) );
       }
    }
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  7. #7
    wossname
    Guest
    I tried all the combinations of Underscores and "asm" to no avail.

  8. #8
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Hmmm...that's because it's a totally dodgy syntax
    This section was written by Marc Brooker

    This is not an assembler tutorial, it is intended for someone who already
    can do assembler and wishes to learn to write inline assembler in DJGPP.

    Why would I want Inline Assembler?
    There are a variety of reasons why you would opt to include inline assembler
    in your program. The djgpp compiler outputs high quality code, but it is not
    always the fastest/smallest you can get away with. Sometimes, you would want
    to write your own code in assembler to achieve your aims. This is most
    important in an inner loop which is likely to be executed more then 10 times
    per second. If you have code that is only executed once, then it your code
    would not make too much of an impact on the speed of your program.

    Why wouldn't I want Inline Assembler?
    You can also make things worse by adding inline assembler. If the code that
    GCC would have created or the library code that you are replacing is faster,
    you will make your program slower. Often the assembler code that you write
    is not as stable as DJGPP's code, but you can counter this by writing code
    that is more stable :-). A lot of people tend to make speed/stability
    tradeoffs, IMO this is stupid if taken too far.

    Using Inline Assembler
    There are some things to note when using inline assembler in DJGPP, firstly,
    DJGPP uses the AT&T format, not the Intel format that most people are used
    to. In the AT&T format, the operands are reversed. If you use a register as
    an operand, prefix it with % and immediate values get a $. You also have to
    add a suffix to the instructions to specify the size of the operands.

    movl %ecx, %ebx

    Notice the 'l' at the end of mov. This specifies that the instruction is
    working on 32 bit operands. 'w' indicates that the instruction is using 16
    bit operands and 'b' for 8 bit.

    So, with all that under your belt, how do you actually add it into your
    code? You use the asm keyword. It takes the following form.

    asm("instructions" : outputs : inputs : clobber list);

    You don't actually need to use the last three, but for longer code you will
    need them. Let's see what they do.

    asm ("
    pushl %%eax
    movl %1, %%eax
    movl %2, %%ebx
    addl %%ebx, %%eax
    movl %%eax, %0
    popl %%eax"
    : "=g" (i)
    : "g" (j), "g" (k)
    : "bx" );

    Wow. Let's go through that piece of code step by step. The actual code, as
    you can probably figure out, adds j and k and puts the output in i. Firstly,
    what's with the '%%'? If you have any inputs or outputs, then you must put
    %% before your register names. Next up, the input list. Who is 'g'? G simply
    tells the compiler to put the argument anywhere. You can then reference them
    in order, %0 is i, %1 is j and %2 is k. '=g' tells the compiler that it is
    output. We put ebx into the clobbered list because it gets clobbered.

    We have seen our first example and learned a lot in the last couple of
    lines. Go get yourself a cup of strong coffee (or maas if you don't drink
    coffee:-) and read on. Next up, what about 'jmp' and it's friends. You can
    use them but you must suffix your lables with b for backward and f for
    forward, the following piece will illustrate this.

    asm ("0:
    //some stuff
    jmp 0b
    //more stuff
    jmp 1f
    1:" );

    That is all said and done, but what about memory references, are they
    different too? Yeah, like everything, they are different, for example, if
    you wanted to access ebp + 4 then you would use the line movl 4(%ebp), %eax.
    Wow, that is weird, I hear people saying. Depending on what you do in
    assembler you might never need to use this syntax, it's full form is
    disp(base, index, scale).

    That should get you rolling as far as porting that app that uses inline asm
    from a different system. I apologize for any problems in this I wrote it one
    nigh at about 11:30 for a friend who was starting in DJGPP.
    From the DJGPP manua;

    Have fun
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  9. #9
    denniswrenn
    Guest
    What is circular bitwise shifting?

  10. #10
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Normally, if you do a bitwise left shift by 8 bits (a byte), that byte is shifted into oblivion. A circular left shift (or rotate left, as the x86 instruction ROL implies) tags it back onto the other end.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  11. #11
    wossname
    Guest
    I abandoned the ASM cos it was too much of a faff.

    I'm using this instead:

    Code:
    typedef unsigned long int ULI;
    
    ULI Shift(ULI Number, int Offset)
    {
      return ((Number << Offset) | (Number >> (32-Offset)));
    }

  12. #12
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Fair enough, but that makes a huge pile of object code as compared to a couple of instructions
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  13. #13
    wossname
    Guest
    Well, I'm only a novice at C++ really. I can't get ASM working within my programs no matter what I do, so I'll take a bunch of object code over zero functionality anyday .

    Anyway, since it is a high-data-throughput program I'll have to look into this ASM more deeply later on when its all done and working.

    Curse VB for not having unsigned integers, longs etc...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width