You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

x86 MASM汇编中数组大小导致斐波那契输出垃圾值问题

问题原因与解决方案

问题根源

  • 你的.data段中,array和fib变量连续存放,fib紧跟在array之后。fib是一个存储数组基地址的DWORD变量,而你通过[fib + esi * 4]访问数组元素时,每次都会先读取fib存储的基地址再计算偏移。
  • 当array设为41个DWORD元素时,数组占用41*4=164字节。循环中esi增大到特定值(如esi=41)时,计算出的偏移地址会恰好指向fib变量本身的位置。此时执行mov [fib + esi * 4], eax会把fib中存储的数组基地址覆盖成当前斐波那契数值,后续访问数组时使用的是被篡改的错误基地址,自然会读出垃圾值。
  • 数组越大,fib离array末尾越远,计算前41个斐波那契数的偏移地址碰不到fib的位置,因此不会出现覆盖问题,结果正确。

修复方法

以下两种方式任选其一,即可将数组设为41个元素并得到全部正确结果:

方式1:调整变量顺序

将fib变量移到array前面,确保数组的偏移永远不会覆盖fib:

.data
display BYTE "Fibonacci number ", 0
equal BYTE " = ", 0
fib DWORD OFFSET array  ; 将fib移到array之前
array DWORD 41 DUP(0)   ; 设为41个元素

方式2:用寄存器存储数组基地址

直接用寄存器(如EBX)存储数组基地址,避免使用.data段变量带来的覆盖风险,同时提升代码效率:

INCLUDE Irvine32.inc

.data
display BYTE "Fibonacci number ", 0
equal BYTE " = ", 0
array DWORD 41 DUP(0)  ; 设为41个元素

.code
main PROC
    mov ebx, OFFSET array  ; 用EBX存储数组基地址

    mov [ebx], 0
    mov [ebx + 4], 1
    mov [ebx + 8], 1

    mov ecx, 3
    mov esi, 0
    
L1:
    mov edx, OFFSET display
    call WriteString
    
    mov eax, esi
    call WriteDec
    
    mov edx, OFFSET equal
    call WriteString
    
    mov eax, [ebx + esi * 4]
    call WriteDec
    
    call Crlf
    inc esi
    
loop L1

    mov ecx, 38 
    mov esi, 3  
    
Fibo:
    mov edx, OFFSET display
    call WriteString
    
    mov eax, esi
    call WriteDec
    
    mov edx, OFFSET equal
    call WriteString
    
    mov eax, [ebx + esi * 4 - 4]
    add eax, [ebx + esi * 4 - 8]
    mov [ebx + esi * 4], eax
    
    mov eax, [ebx + esi * 4]
    call WriteDec
    
    inc esi
    call Crlf
    
loop Fibo

exit
main ENDP
end main

内容的提问来源于stack exchange,提问作者newGuy77

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 02:47:23