时间:2010-07-24 03:01:23

标签: c

3 个答案:

答案 0 :(得分:4)

答案 1 :(得分:0)

这是一个替代实现,当n> = 32时交换值。它还处理n = 0或n = 32时的情况,这会导致hi >> (32 - n)移位多于类型宽度,导致未定义行为。

void
rot64 (uint32_t hi, uint32_t lo, uint32_t n, uint32_t *hi_out, uint32_t *lo_out)
{
    /* Rotations go modulo 64 */
    n &= 0x3f;

    /* Swap values if 32 <= n < 64 */
    if (n & 0x20) {
        lo ^= hi;
        hi ^= lo;
        lo ^= hi;
    }

    /* Shift 0-31 steps */
    uint8_t shift = n & 0x1f;

    if (!shift) {
        *hi_out = hi;
        *lo_out = lo;
        return;
    }

    *hi_out = (hi << shift) | (lo >> (32 - shift));
    *lo_out = (lo << shift) | (hi >> (32 - shift));
}

答案 2 :(得分:0)

这是组装时的样子

;-------------------------------------------------------------------------------
; Rol64
; EXTERN_C UINT64 CDECL Rol64(UINT64,INT);
;-------------------------------------------------------------------------------
; In:
;   eax:edx = 64bit value to rotate
;   dl      = number of bits to rotate
; Return:
;   rotated value in eax:edx
;-------------------------------------------------------------------------------

BeginCDECL Rol64

   ;- parameters --------------------------------------------------
   in_Lo  EQU DWORD PTR [esp + 04h]
   in_Hi  EQU DWORD PTR [esp + 08h]
   in_Cnt EQU DWORD PTR [esp + 0Ch]


 ; get parameters
 mov eax, in_Lo
 mov edx, in_Hi
 mov ecx, in_Cnt

 ; count modula 64
 and cl, 03Fh

 ; zero?
 cmp cl, 0
 jz short rol64_exit

 ; shift above 32? then exchange hi/lo
 cmp cl, 020h
 jc short rol64_noxchg
   xchg eax, edx
 rol64_noxchg:

 ; save registers
 push ebx

 ; low, forward
 mov ebx, eax
 shl ebx, cl
 push ebx

 ; high, forward
 mov ebx, edx
 shl ebx, cl

 ; get reverse count
 mov ch, 32
 sub ch, cl
 mov cl, ch

 ; high, reverse
 shr eax, cl
 or ebx, eax

 ; low, reverse
 pop eax
 shr edx, cl
 or eax, edx

 ; move tmp to high
 mov edx, ebx

 ; restore registers
 pop ebx

 ; done
 rol64_exit:
 ret

EndCDECL Rol64