一千萬個為什麽

搜索

幫助改進簡單的裝配功能

我剛剛在作業中交出了這個功能。它完成了(因此沒有家庭作業標簽)。但我想看看如何改進。

本質上,函數使用以下公式對1和給定數字之間的所有整數的平方求和:

n(n+1)(2n+1)/6

其中 n 是最大數量。

下面的函數用於捕獲任何溢出,如果發生任何溢出則返回0。

UInt32 sumSquares(const UInt32 number)
{
    int result = 0;
    __asm
    {
        mov eax, number  //move number in eax
        mov edx, 2       //move 2 in edx
        mul edx          //multiply (2n)
        jo end           //jump to end if overflow
        add eax, 1       //addition (2n+1)
        jo end           //jump to end if overflow
        mov ecx, eax     //move (2n+1) in ecx

        mov ebx, number  //move number in ebx
        add ebx, 1       //addition (n+1)
        jo end           //jump to end if overflow

        mov eax, number //move number in eax for multiplication
        mul ebx         //multiply n(n+1)
        jo end          //jump to end if overflow
        mul ecx         //multiply n(n+1)(2n+1)
        jo end          //jump to end if overflow
        mov ebx, 6      //move 6 in ebx
        div ebx         //divide by 6, the result will be in eax

        mov result, eax //move eax in result

end:
    }

    return result;
}

基本上,我想知道我可以在那裏改進什麽。在最佳實踐方面。有一件事聽起來很明顯:更智能的溢出檢查(只需檢查一下最大輸入會導致溢出)。

最佳答案

    mov eax, number  //move number in eax
    mov ecx, eax     //dup in ecx
    mul ecx          //multiply (n*n)
    jo end           //jump to end if overflow
    add eax, ecx     //addition (n*n+n); can't overflow
    add ecx, ecx     //addition (2n); can't overflow
    add ecx, 1       //addition (2n+1); can't overflow
    mul ecx          //multiply (n*n+n)(2n+1)
    jo end           //jump to end if overflow
    mov ecx, 6       //move 6 in ebx
    div ecx          //divide by 6, the result will be in eax

    mov result, eax //move eax in result

強度降低:增加而不是乘法。

通過分析,減少溢出檢查(您可以按照您的描述做得更好)。

將值保存在寄存器中,而不是返回堆棧中的參數。

選擇仔細註冊,以便不會覆蓋可重復使用的值。

轉載註明原文: 幫助改進簡單的裝配功能