x86_64 AT&T组件中的旋转功能

时间:2018-10-30 22:33:56

标签: c assembly x86-64 att

我在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 long或其他内容有问题吗?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

您的asm中有一个错误:right中的循环分支执行jmp loop而不是jmp right。至少是您的错误中的一个,如果还有更多错误,则为IDK。 (更新:@zch发现了C语言中的错误,该错误说明了您提到的截断。)

如果您使用比loop更好的名称,这将更容易发现。例如left

但是您无论如何都不应该循环播放。 x86具有rol %cl, %rdiror %cl, %rdi,您可以使用它们代替循环。只需mov%ecx的班次,就像mov %esi, %ecx一样。