0

我在 AT&T 64 位汇编中实现了一个旋转功能,并且无法在我的代码中获得正确的输出。

我要实现的功能是

unsigned long rotate(unsigned long val, ul num, ul dir); 

Val是我想要旋转的值,num是多少次,方向是左还是右,0 是右,1 是左。

我的汇编代码:

.global rotate

rotate: #value = %rdi
        #num = %rsi 
        #direction = %rdx 
        mov %rsi, %r10 #puts num into register
        test %rdx, %rdx 
        jz right #if rdx is 0 jump to rotate right
        #else go to loop right below which rotates left
loop: 
     test %r10, %r10 #if num is 0 I am done
     jz done 
     rol $1, %rdi #rotate left 1 bit
     dec %r10 #decrement my count
     jmp loop #jump to top of loop 

 right: #same logic as left 
      test %r10, %10 
      jz done 
      rol $1, %rdi  
      dec %r10 
      jmp loop 
 done: 
      mov %rdi, %rax
      ret 

我的 C 代码:

#include <stdio.h> 
extern unsigned long rotate(unsigned long val, unsigned long num, unsigned long direction); 

int main()
{
unsigned long v,n,d; 
v = 0xDEADBEEFDEADBEEF; 
n = 2; 
d = 1; 

printf("%x\n ", rotate(v,n,d));    
}

当我编译和运行时,我得到了值0x7AB6FBBF,当我应该得到0x7AB6FBBF7AB6FBBF.

我的指令没有发送unsigned longs 或其他东西有什么问题吗?

4

2 回答 2

1

printf("%x", a)适用于unsigned int类型。在unsigned long您需要"%lx"用作格式字符串时。

于 2018-10-30T22:45:09.040 回答
1

您的 asm 中有一个错误:循环分支中的do而right不是. 至少这是您的错误之一,如果还有更多错误,IDK。(更新:@zch 发现了您的 C 中的错误,它解释了您提到的截断。)jmp loopjmp right

如果您使用的名称比loop. 例如left

但无论如何你不应该循环。x86 具有rol %cl, %rdiand ror %cl, %rdi,您可以使用它来代替循环。只需mov将您的班次计入%ecx,例如mov %esi, %ecx

于 2018-10-30T22:45:37.180 回答