Assembly 集合最短形式的Collatz猜想
我们有一个任务,我们必须在64位nasm汇编中编写collatz猜想,只使用13个或更少的命令(包括RET)。现在我们想知道你能减少多少。我们目前在9点。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
以下是伪代码中的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
,因为只有三个字节。我使用的是或
,因为我们优化的是尺寸,而不是速度。