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

如何仅用算术运算和逻辑门在ASM中筛选两数大小并存入指定变量

无分支实现两数大小排序的汇编方案

核心思路

利用算术运算+符号位掩码实现无分支的大小判断,全程不需要jmp类分支指令。核心逻辑是通过两数差值的符号位生成全1/全0掩码,再用掩码选择对应数值存入big和small。

代码实现(x86 32位 NASM 语法)

section .data
    num1 dd 150     ; 输入变量1
    num2 dd 80      ; 输入变量2
    big  dd ?       ; 存储较大值
    small dd ?      ; 存储较小值

section .text
    global _start
_start:
    ; 生成差值符号掩码
    mov eax, [num1]
    sub eax, [num2]   ; eax = num1 - num2
    cdq               ; 符号位扩展到edx:差值为负则edx=0xFFFFFFFF,否则edx=0x00000000

    ; 计算big
    mov ebx, [num1]
    mov ecx, [num2]
    sub ecx, ebx      ; ecx = num2 - num1
    and ecx, edx      ; 仅当num1 < num2时,保留num2-num1;否则为0
    add ebx, ecx      ; num1小则加num2-num1得到num2,否则保持num1
    mov [big], ebx

    ; 计算small(两种方式选其一即可)
    ; 方式1:用总和减big(最简洁)
    mov eax, [num1]
    add eax, [num2]
    sub eax, [big]
    mov [small], eax

    ; 方式2:复用掩码逻辑(和big对称)
    ; mov ebx, [num2]
    ; mov ecx, [num1]
    ; sub ecx, ebx      ; ecx = num1 - num2
    ; and ecx, edx      ; 仅当num1 < num2时,保留num1-num2;否则为0
    ; add ebx, ecx      ; num2大则加num1-num2得到num1,否则保持num2
    ; mov [small], ebx

    ; Linux环境退出程序
    mov eax, 1
    xor ebx, ebx
    int 0x80

关键指令说明

  • cdq:将EAX的符号位扩展到EDX,自动生成我们需要的掩码。这是实现无分支判断的核心,避免了jge/jl等分支指令。
  • 掩码运算:and ecx, edx利用掩码筛选有效差值,只有当num1更小时,差值才会被保留并参与后续加法,最终得到较大值。

关于和差平均法的问题

你尝试的(num1+num2+abs(num1-num2))/2方案,容易出现整数溢出:当num1和num2都是较大的正数时,两数之和会超出寄存器范围,导致计算结果错误。而掩码法不存在这个问题,只要两数的差值在寄存器范围内即可正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 20:51:28