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

汇编程序求助:判断三数和奇偶性的函数始终返回true

汇编程序判断三数和奇偶性的问题排查与修复

核心问题分析

  • 参数栈顺序完全错误
    调用时压栈顺序是push CX → push BX → push AX,栈遵循先进后出规则,栈顶到栈底的实际顺序是AX → BX → CX。但你在oddtest里的弹出顺序是pop AX → pop BX → pop CX,这导致三个变量的值完全错位:原本的value1被赋值给CX,value3被赋值给AX,后续计算的总和完全错误。

  • 奇偶判断逻辑存在致命漏洞
    用循环减2的方式判断奇偶时,若总和为负数奇数,两次dec(DX)后DX会变得更小(更负),cmp(DX,0)后jg sub_repeat不会触发(仅当有符号数大于0时生效),直接跳出循环且不会命中je even_result,最终无论总和是什么都会进入奇数分支。

  • 过程声明与调用方式不匹配
    过程声明用了var(传引用),但实际调用时是直接压入寄存器的值(传值),虽然你实际想实现传值,但var的声明会误导汇编器;同时@noframe需要手动处理栈平衡,原程序也未做栈清理。

  • 冗余的总和计算
    判断奇偶性不需要计算完整总和,只需看三个数的最低位(第0位):奇数最低位为1,偶数为0。三个数的和的奇偶性等价于三个数最低位的异或(或相加后取最低位),逻辑更简单且不会出现溢出问题。

修复后的代码

program Odd_Number;
#include( "stdlib.hhf" );

static
value1 : int8;
value2 : int8;
value3 : int8;

; 修改为传值声明,移除@noframe让汇编器自动处理栈帧(更安全)
procedure oddtest( val v1 : int8; val v2 : int8; val v3 : int8 ); @nodisplay; 

begin oddtest;

    mov(0, DL);
    ; 取三个数的最低位相加,最终只保留结果的最低位
    mov(v1, AL);
    and(1, AL); ; 仅保留最低位
    add(AL, DL);

    mov(v2, AL);
    and(1, AL);
    add(AL, DL);

    mov(v3, AL);
    and(1, AL);
    add(AL, DL);

    and(1, DL); ; 最终结果:1=奇数,0=偶数

    cmp(DL, 1);
    je is_odd;

    stdout.put("sumIsOdd returned false!");
    jmp done;

is_odd:
    stdout.put("sumIsOdd returned true!");

done:
    ret();
end oddtest;

begin Odd_Number;

stdout.put( "Provide value1:" );
stdin.get(value1);
stdout.put( "Provide value2:" );
stdin.get(value2);
stdout.put( "Provide value3:" );
stdin.get(value3);

; 按过程参数顺序直接压入变量值
push(value3);
push(value2);
push(value1);
call oddtest;

end Odd_Number;

优化说明

  • 改用val声明参数(传值),配合移除@noframe,让汇编器自动处理栈帧和返回地址,避免手动操作栈的错误。
  • 用位运算直接判断最低位,逻辑高效,同时规避了负数、溢出等边界问题。
  • 调用时直接压入变量值,无需先加载到寄存器,简化代码结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:35:28