logical ror c++ integer 4bytes byte rotation

Assembly code:
1
2
ROR AL,3
MOV BYTE PTR DS:[EDI],AL

In the code above the byte found at AL is ror-ed 3 times and then the result gets stored in the byte at address EDI.
the equivalent to c++ is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
unsigned char byte_rotateright( unsigned char v, unsigned char x ){
    int i=0;
    loop:
    if( i==x )
        return v;
    i++;
	unsigned char temp = v & 1;  // extract the low bit
	v >>= 1;  // shift right
	v |= ( temp<<7 ); // put the previous low bit in the high bit
    goto loop;
}

//call method
unsigned char al;
al = byte_rotateright( al,3 );


does someone know how to make the above c++ function work with 4 bytes ? (int)
Ever heard of for loops? And it works the same with 4 bytes, except that the high bit obviously is a different one (sizeof(v)*CHAR_BIT-1).
Last edited on
yes, but i used the goto instruction because, in assembly, the for structure makes a few calls when the goto instruction does not, it just makes a JMP label;

thanks:
here's the correct result:
1
2
3
4
5
6
7
8
9
10
11
unsigned int int_rotateright( unsigned int v, unsigned char x ){
    int i=0;
    loop:
    if( i==x )
        return v;
    i++;
	unsigned int temp = v & 1;  // extract the low bit
	v >>= 1;  // shift right
	v |= ( temp<<31 ); // put the previous low bit in the high bit
    goto loop;
}
Last edited on
v |= ( temp<<7 );
You need to change this line. 7 is suitable for an 8-bit value.
The number of bits by which temp is left-shifted, is found by taking the size of the variable in bytes*8 - 1.
yes, but i used the goto instruction because, in assembly, the for structure makes a few calls when the goto instruction does not, it just makes a JMP label;

That's nonsense. Only try to "optimize" if you really know what you're doing - otherwise, do it the normal way.
Last edited on
thanks everyone, i got it :)
anyways, i am disassembling my c++ program and i want the code to be as clear as possible.
and goto surely does.
how about rol ?
how about rol ?

It will be very similar to ror, except for some minor adjustments.
Last edited on
anyways, i am disassembling my c++ program and i want the code to be as clear as possible.
and goto surely does.

If you're using a compiler that is not older than 20 years, you'll find that using for will produce equivalent code.
goto:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
_Z15int_rotaterightjh:
	movzbl	%sil, %esi
	xorl	%edx, %edx
	movl	%edi, %eax
	testl	%esi, %esi
	je	.L7
.L8:
	addl	$1, %edx
	roll	$31, %eax
	cmpl	%esi, %edx
	jne	.L8
.L7:
	rep
	ret


for:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
_Z15int_rotaterightjh:
	movzbl	%sil, %esi
	movl	%edi, %eax
	testl	%esi, %esi
	je	.L7
	xorl	%edx, %edx
.L8:
	addl	$1, %edx
	roll	$31, %eax
	cmpl	%esi, %edx
	jl	.L8
.L7:
	rep
	ret


1
2
3
4
5
6
7
8
unsigned int int_rotateright( unsigned int v, unsigned char x ){
    for (int i=0;i<x;i++) {
	      unsigned int temp = v & 1;  // extract the low bit
	      v >>= 1;  // shift right
	      v |= ( temp<<31 ); // put the previous low bit in the high bit
    }
    return v;
}
Last edited on
> how about rol ?

Symmetric wrt ror.

1
2
3
4
5
6
7
8
9
include <cstdint>

constexpr unsigned int NBITS = 32U ;

inline std::uint32_t ror( std::uint32_t n, std::uint8_t by )
{ by %= NBITS ; return ( n << by ) | ( n >> (NBITS-by) ); }

inline std::uint32_t rol( std::uint32_t n, std::uint8_t by )
{ by %= NBITS ; return ( n >> by ) | ( n << (NBITS-by) ); }



it's what I've read from some article, i didn't even tried to see how it compiles.
and thanks for enlightening me.
i have checked, and it does a pretty good job

i can't figure though the code for rol

don't you think c++ should have rol and ror included in iostream ?
Last edited on
Yeah, you would find it in hundreds of places.

Compiles to a straightforward translation from C++ to assembly:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*///// ror (out of line) ////////////
/////  with gcc 4.8 -O3 //////////////
	pushl	%ebx
	movl	$32, %ecx
	movzbl	12(%esp), %edx
	movl	8(%esp), %ebx
	andl	$31, %edx
	movzbl	%dl, %eax
	subl	%eax, %ecx
	movl	%ebx, %eax
	shrl	%cl, %eax
	movl	%edx, %ecx
	sall	%cl, %ebx
	orl	%ebx, %eax
	popl	%ebx
	ret
//////////////////////////////////////*/



> i can't figure though the code for rol

It is identical, except for the direction of the two bit-wise shifts.
Last edited on
Topic archived. No new replies allowed.