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

Irvine32汇编杨辉三角程序:第5行后输出乱码问题排查

问题分析与解决方案

1. 核心问题:binCoeff 变量赋值错误

程序在计算杨辉三角边界值(即每行首尾的1)时,仅向binCoeff(DWORD类型,4字节)写入了单字节的1,导致高3字节保留了之前计算的残留值,最终输出错误的大数或乱码。

在nChooseK过程的SetOne段中:

SetOne:
    MOV     [binCoeff], 1           ; 错误:仅写入单字节,未覆盖全部4字节

由于MASM默认将立即数1视为BYTE类型,这条指令只会修改binCoeff的最低1字节,剩余3字节仍为之前计算的残留数据,导致读取时得到错误的DWORD值。

2. 修复方案

方案一:通过寄存器写入完整DWORD值

修改SetOne段,先将1加载到EAX(32位寄存器),再写入binCoeff:

SetOne:
    MOV     EAX, 1                  ; 将1加载到32位寄存器
    MOV     [binCoeff], EAX         ; 写入完整的4字节DWORD值
    JMP     EndCalculation
方案二:显式指定DWORD类型

直接使用DWORD PTR强制写入4字节:

SetOne:
    MOV     DWORD PTR [binCoeff], 1 ; 显式指定为DWORD类型
    JMP     EndCalculation

3. 附加优化:遵循寄存器调用约定

PrintPascalRow过程修改了EBX(属于callee-saved寄存器),但未保存和恢复该寄存器。虽然当前逻辑中EBX值未被改变,但遵循调用约定能避免潜在问题:

PrintPascalRow PROC
    ; 新增保存EBX
    PUSH    EAX
    PUSH    EDX
    PUSH    ESI
    PUSH    EDI
    PUSH    EBX                     ; 保存EBX

    MOV     ESI, 0

RowElementLoop:
    MOV     EBX, [currentRow]
    ; ... 原有逻辑 ...

EndRow:
    ; 新增恢复EBX
    POP     EBX                     ; 恢复EBX
    POP     EDI
    POP     ESI
    POP     EDX
    POP     EAX
    RET
PrintPascalRow ENDP

问题解答

  1. 第5行及以后输出乱码的原因:边界值赋值时仅写入单字节,导致binCoeff残留高字节数据,打印出错误的大数,表现为乱码或数字拼接。
  2. 空格打印是否有问题:空格打印逻辑正确(通过MOV DL,32和WriteChar),仅存在末尾多余空格的 cosmetic 问题,不影响功能。
  3. 寄存器管理问题:PrintPascalRow未遵循调用约定保存EBX,虽当前未引发错误,但修复后更健壮;核心问题是binCoeff的DWORD赋值错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 16:00:54