 |
 |
 |
 |
| on my pc your explanation is lost amongst misformated html.
I was flored when i had to write my own rotate functions for java.
in c++ though its not necesary
__asm
{
mov eax,MyVar;
rol eax,8;
mov MyVar,eax;
} |
|
 |
| krashnburn's code works on a 80x86 PC using Microsoft C++, but if it's preferable to write code that works on other platforms, you still have to write your own rotate functions. Note that his code will work in C if you're using Microsoft C++, too.
Basically, here's some simple rotate code:
int WORD_LENGTH;
int rol(int value, int places)
{
return (value<<places)|(value>>(WORD_LENGTH-places);
}
int ror(int value, int places)
{
return (value>>places)|(value<<WORD_LENGTH-places);
}
In case you're wondering, here's one way to calculate WORD_LENGTH:
void CALC_WORD_LEN(void)
{
unsigned int x=~0;
int i=1;
while(x>>=) i++;
}
|
|
 |
| | Oops... I forgot to put the line WORD_LENGTH=i; into the CALC_WORD_LEN() function (it goes at the end, after the while loop). |
|
 |
| adsafde, is there not an error in the while loop?
while(x>>=)
void CALC_WORD_LEN(void)
{
unsigned int x=~0;
int i=1;
while(x>>=?) i++;
WORD_LENGTH=i;
} |
|
 |
| | Besides that, you're not very likely to want a rotation if you don't know its size. Feel free to use uint16_t and friends from stdint.h. |
|
 |
| |
 |
| I think there is an easier way to calculate WORD_LEN
#define WORD_LEN(w) (8*sizeof(w))
or either
#define WORD_LEN(w) (sizeof(w)<<3)
|
|
 |
| The code for ror
int ror(int value, int places)
{
return (value>>places)|(value<<WORD_LENGTH-places);
}
works fine for value>=0, but if value<0 it fails, since value is a signed int, value>>places
inserts the sign bit on the left.
Fully (I hope) functional code should be
#define WORD_LENGTH (8*sizeof(value))
int rol(unsigned value, int places)
{
return (value<<places)|(value>>(WORD_LENGTH-places);
}
int ror(unsigned int value, int places)
{
return (value>>places)|(value<<WORD_LENGTH-places);
}
#undef WORD_LENGTH
|
|
 |
| For java:
Integer.rotateLeft(int i, int distance)
Integer.rotateRight(int i, int distance)
since 1.5 :) |
|
 |
| | I forgot to put the line WORD_LENGTH=i; into the CALC_WORD_LEN() function (it goes at the end, after the while loop). online game |
|
 |
| The thread is old as hell, but i was looking for the same thing as inline assembler function in gcc. here is my solution, maybe it helps someone:
#include <stdio.h>
#include <inttypes.h>
__inline__ rol(uint32_t operand, uint8_t width) {
__asm__ __volatile__ ("rol %%cl, %%eax"
: "=a" (operand)
: "a" (operand), "c" (width)
);
}
int main ()
{
uint32_t testint = 0x80000000;
testint = rol(testint,1);
printf("%X\n", testint);
return 0;
}
Short expl.: function rol receives two ints (one 32 bit, one 8), the 32 bit var is stored in EAX ("a"), the 8 bit in the low part of ECX (CL) ("c"). rol/ror etc can receive a constant or memory or register as rotation width, if its a register it has to be CL, thats why the code is like that. Now rol EAX CL bits wide and return EAX (=a). Since its a function, the to be rotated var has to be reassigned with the return value of rol().
If its done inline with no extra function, the var neednt to be reassigned:
#include <stdio.h>
#include <inttypes.h>
int main ()
{
uint32_t testint = 0x80000000;
uint8_t width = 3;
//testint = rol(testint,1);
__asm__ __volatile__ ("rol %%cl, %%eax"
: "=a" (testint)
: "a" (testint), "c" (width)
);
printf("%X\n", testint);
return 0;
}
-Tim |
|
 |
| Hello,
I have further improved the code above. ror/rol can use memory directly. The code bellow is for X64 (AMD) architecture:
#define ror(i,by) \
__asm__ ( \
"rorq %b1,%q0"\
:"+g" (i) \
:"Jc" (by) )
/*no clobber list*/
#define rol(i,by) \
__asm__ ( \
"rolq %b1,%q0"\
:"+g" (i) \
:"Jc" (by) )
int main() {
uint8_t a=1;
uint64_t b=1;
ror(b,a);
printf("%0llX\n",b);
rol(b,a);
printf("%0llX\n",b);
ror(b,1);
printf("%0llX\n",b);
rol(b,1);
printf("%0llX\n",b);
return 0;
}
[/code]
Please notice that I'm using
+mr => + means that it's used for both input&output
mr means that it can be memory or register
Jc => means either integer in range 0..63 or c register
%b1,%0
%b1 => width of the first operand is 8 bits.
rorq => means that we are working with m64 (64 bit memory) - Important for memory arguments.
ror(b,a); translates into
rorq %cl,-1144(%rbp)
while
ror(b,1); translates into
rorq $1,-1144(%rbp)
So the compiler can either copy number to be rotated into register or leave it in memory. It can also decided if number of bits to be shifted needs to be copied into cl register or it's already known during the compilation time.
Have fun with inline asm.
Jiri |
|
 |
| Hi Tim,
there is one mistake in your code - missing return statement. Your code works well as long as the function is NOT INLINED (gcc without any optimization enabled). When you force gcc to really inline the function (gcc -O1) it does not work anymore. I have tested it on operand 0x1. ROL(0x1,1) should give 0x2.
gcc -O1 -o strange strange.c && strange
D301BC98
gcc -o strange strange.c && strange
2
Actually, it prints random number - the value of esi register.
Correct code is bellow:
__inline__ uint32_t ror32f(uint32_t operand, uint8_t width) {
__asm__ __volatile__ ("rorl %b1, %0"
: "+mr" (operand)
: "Jc" (width)
);
return operand;
}
Just my 2 cents.
Jiri
|
|
 |
| |
 |
| That is certainly a number of peak performance goods. Couldn't know that will ideas may be this specific various. Appreciate your each of the eagerness to make available this sort of information below.
obat asam urat
|
|
 |
| |
 |
 |
 |
 |
Anonymously add a comment: (or register