Assembly 集合最短形式的Collatz猜想

Assembly 集合最短形式的Collatz猜想,assembly,64-bit,nasm,Assembly,64 Bit,Nasm,我们有一个任务,我们必须在64位nasm汇编中编写collatz猜想,只使用13个或更少的命令(包括RET)。现在我们想知道你能减少多少。我们目前在9点。 以下是伪代码中的collatz猜想,以供参考: 这是我们到目前为止的代码。注意事项: 我们的一位导师说我们可以删除XOR rax,rax,因为一些调用约定,它已经是零了。但它在我的电脑上不工作,所以我把它包括在这里。 我知道两个LEA可能是最明显的减少,但我们想不出一个方法,因为*6似乎是唯一不可能用LEA做的事情 GLOBAL colla

我们有一个任务,我们必须在64位nasm汇编中编写collatz猜想,只使用13个或更少的命令(包括RET)。现在我们想知道你能减少多少。我们目前在9点。
以下是伪代码中的collatz猜想,以供参考:

这是我们到目前为止的代码。注意事项:
我们的一位导师说我们可以删除XOR rax,rax,因为一些调用约定,它已经是零了。但它在我的电脑上不工作,所以我把它包括在这里。
我知道两个LEA可能是最明显的减少,但我们想不出一个方法,因为*6似乎是唯一不可能用LEA做的事情

GLOBAL collatz
SECTION .text

collatz:
    XOR rax, rax

    .while:
        SHR rdi, 1
        JNC .even
            LEA rdi, [rdi*2+1]
            LEA rdi, [rdi*2+rdi+1]
        .even:

        INC rax

        CMP rdi, 1
        JA .while
    RET

这有点短:

collatz:
        or     $-1,%eax
.loop:  inc    %eax
        lea    1(%rdi,%rdi,2),%rsi
        shr    %rdi
        cmovc  %rsi,%rdi
        jnz    .loop
        ret
或者,在nasm语法中:

collatz:
        or     eax,-1
.loop:  inc    eax
        lea    rsi,[rdi+rdi*2+1]
        shr    rdi
        cmovc  rdi,rsi
        jnz    .loop
        ret

要理解此代码,请密切注意进位标志(CF)和零位标志(ZF)。

不要垃圾邮件标签!你的具体问题是什么?我投票决定把这个问题作为离题题来结束,因为这实际上更像是一个“代码高尔夫”问题。@DavidHoelzer啊,我不知道这是不允许的,因为它在技术上是可以解决的。你建议在哪里问这个问题?“我们的一位导师说,我们可以删除XOR-rax,rax,因为一些调用约定,它已经是零了。”不,这完全是错误的。在无调用约定下,
RAX
保证为0。我认为
RAX
需要始终递增,因此
adc
是错误的。现在看起来不错。哇,这真是聪明。一夜之间,我们有了类似于adc的东西,但这很好,谢谢。请注意,
或eax,-1
eax
有错误的数据依赖性,因此,虽然这是一种将寄存器设置为-1的短方法,但不是一种快速方法。如果您想要速度,并且愿意放弃几个字节,那么可以使用
moveax,-1
。(
xor eax,eax
+
dec eax
是另一个避免虚假数据依赖性的选项,并且仍然比
mov
短)但是,这两种方式可能都不是特别相关,因为它在循环之外。@CodyGray甚至更短的方式可能是
push$-1;弹出%rax
,因为只有三个字节。我使用的是
,因为我们优化的是尺寸,而不是速度。