遞歸函數 Add_Recursion 計算位運算加法,基礎情況 return a,遞歸情況卻漏寫 return 直接調用自身。神奇的是 Add_Recursion(1,1) 仍正確輸出 2。但若在遞歸返回後調用任意函數(如 changestack()),結果變為 3(即 changestack 的返回值)。
x86 呼叫慣例中,整型返回值放在 EAX。遞歸最深層 return a 執行 mov eax, a,隨後各層 ret 時若無賦值指令,EAX 保持不變,主函數讀到正確值。但中間層若調用其他函數,EAX 被覆蓋,導致錯誤傳遞。
changestack 編譯為 mov eax, 3; ret。mov [num], eax 取返回值。return 時,編譯器不生成 mov eax, ...,僅 ret。__asm { mov eax, 3 } // 在遞歸返回後插入
// 主函數將打印 3,證明返回值確實取自 EAX。
MSVC 警告 C4715:「非所有控制路徑都返回值」。C++ 更嚴格直接報錯。結論:所有分支必須顯式 return,切勿依賴寄存器殘值,否則代碼極不穩定,微小修改即導致錯誤。