我在创建一个计算奇数之和结果的 x64 masm 程序时遇到了问题。答案在 RAX 中为 109E82h (1089154d)。我很难弄清楚 masm 是如何工作的,但它太令人困惑了。到目前为止,这是我尝试过的方法,但是 RAX 寄存器中的值不正确。我已经尽我所能,但我不知道我哪里错了。
extrn ExitProcess: proc
.data
fib1 QWORD 0
fib2 QWORD 1
sum QWORD 0
.code
_main PROC
; calculate the Fibonacci sequence up to 10^7
mov rax, 10000000
mov rcx, fib1
mov rdx, fib2
FIB_LOOP:
add rcx, rdx
mov fib1, rdx
mov fib2, rcx
cmp rcx, rax
jle FIB_LOOP
; add odd numbers to the sum
mov rcx, fib1
add rcx, rdx ; rdx contains the last even Fibonacci number
SUM_LOOP:
test cl, 1 ; check if the current number is odd
jz SKIP_ADD
add sum, rcx
SKIP_ADD:
add rcx, rdx
mov rdx, rcx
cmp rcx, rax
jle SUM_LOOP
; exit the program
mov rax, sum
call ExitProcess
_main ENDP
END
但我不知道我哪里错了。
嗯,我不明白为什么你的程序的第一部分是计算斐波那契数列到 10^7,当标题提到你需要处理 [0,10^6] 范围内的数字时.这比需要的高 10 倍!在那之后,求和循环进入更大的数字,幸运的是 RAX 限制没有改变,所以这部分很快就退出了。
xor eax, eax ; RAX=0 is Number1 (Fibonacci)
lea ecx, [rax+1] ; RCX=1 is Number2
cdq ; RDX=0 is SumOfOdds
More:
xchg eax, ecx ; -> RCX = 0, 1, 1, 2, 3, 5, 8, ...
add eax, ecx ; -> RAX = 1, 1, 2, 3, 5, 8, 13, ...
test al, 1
jz isEven
add edx, eax ; -> RDX +1, +1, +3, +5, +13, ...
isEven:
cmp eax, 1000000
jb More
test al, 1 ; Keep this one-time correction outside of the loop
jz Done
sub edx, eax ; Take back last addition of an odd Fib
Done:
xchg eax, edx ; Final result in RAX
这可能是一个有趣的选择(未经测试):
xor eax, eax ; RAX=0 is Number1 (Fibonacci)
lea ecx, [rax+1] ; RCX=1 is Number2
cdq ; RDX=0 is SumOfOdds
SumIt:
add edx, eax ; -> RDX +1, +1, +3, +5, +13, ...
More:
xchg eax, ecx ; -> RCX = 0, 1, 1, 2, 3, 5, 8, ...
add eax, ecx ; -> RAX = 1, 1, 2, 3, 5, 8, 13, ...
test al, 1
jz More
cmp eax, 1000000
jb SumIt
xchg eax, edx ; Final result in RAX