【问题标题】:Collatz Conjecture in Assembly shortest form装配最短形式的科拉茨猜想
【发布时间】:2017-06-28 04:48:53
【问题描述】:

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

这是我们目前的代码。几点说明:
我们的一位导师说我们可以删除 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

【问题讨论】:

  • 不要垃圾标签!您的具体问题是什么?
  • 我投票结束这个问题,因为这更像是一个“代码高尔夫”问题。
  • @DavidHoelzer 啊我没有意识到这是不允许的,因为它在技术上是可以解决的。你建议在哪里问这个?
  • “我们的一位导师说我们可以删除 XOR rax,rax 因为某些调用约定,它已经为零了。” 不,完全错误。在没有调用约定的情况下,RAX 保证为 0。

标签: assembly 64-bit nasm


【解决方案1】:

这有点短:

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)。

【讨论】:

  • 我相信rax 需要一直递增,所以adc 是错误的。
  • 现在看起来不错。
  • 哇,这真是太聪明了。一夜之间,我们有了与 adc 类似的东西,但这很棒,谢谢。
  • 请注意or eax, -1eax 有一个错误的数据依赖,因此虽然这是将寄存器设置为-1 的 方法,但它不是快速方式。如果你想要速度,并且愿意放弃几个字节,你会使用mov eax, -1。 (xor eax, eax + dec eax 是另一种避免错误数据依赖的选项,并且仍然比mov 短。)不过,这两种方式可能都不是特别相关,因为它在循环之外。
  • @CodyGray 更短的方法可能是push $-1; pop %rax,因为它只有三个字节。我使用的是or,因为我们正在优化大小,而不是速度。
猜你喜欢
  • 2011-01-24
  • 1970-01-01
  • 2019-01-03
  • 1970-01-01
  • 2021-11-22
  • 2012-10-22
  • 2022-01-14
  • 2022-12-10
  • 1970-01-01
相关资源
最近更新 更多