【问题标题】:Rotate Function in x86_64 AT&T assemblyx86_64 AT&T 程序集中的旋转功能
【发布时间】:2019-04-04 01:22:21
【问题描述】:

我在 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 或其他什么有问题吗?

【问题讨论】:

  • 那不应该是一个无符号长长吗?
  • 你知道在大多数平台上long 是 32 位的,对吧?
  • @Sneftel:x86-64 System V 具有 64 位 long,并且此代码在 RDI 和 RSI 中采用 args,因此它绝对是 ABI。 (Where is the x86-64 System V ABI documented?)
  • 我把c代码改成全无符号长整数,结果都一样
  • @pigsploof: x86 有rol %cl, %rdi 和ror %cl, %rdi,您可以使用它们来代替循环。只需将 mov 您的班次计入 %ecx。

标签: c assembly x86-64 att


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 我使用循环的原因是因为当我尝试使用 rol %ecx, %rsi 时,我收到了 rol 操作数类型不匹配的错误。我必须使用立即数来编译它,我不知道为什么。
    • @pigsploof 移位和旋转指令只能使用 %cl 或立即数作为计数操作数。
    • @pigsploof:我的回答是 rol %cl, %rsi 是有原因的(felixcloutier.com/x86/RCL:RCR:ROL:ROR.html)。但是mov %esi, %ecx 的效率可能比mov %sil, %cl 或movzbl %sil, %ecx 稍微高一点,所以我建议mov 使用它。 x86 无论如何都会屏蔽移位计数,因此无论是复制或归零寄存器的高位,还是合并到 RCX 的旧值中都无关紧要。
    猜你喜欢
    • 2021-03-05
    • 2021-01-23
    • 2016-08-07
    • 2011-04-09
    • 1970-01-01
    • 2017-10-23
    • 2020-03-20
    • 1970-01-01
    • 2013-03-30
    相关资源
    最近更新 更多