x86 NASM汇编中不同符号数值的正确比较方法
x86 NASM汇编有符号数大小比较解决方案
错误原因说明
你之前得到错误结果的核心原因是混用了无符号数的大小判断逻辑:x86架构中CMP指令执行后会同时修改多个标志位,但判断大小的跳转指令分为两套独立逻辑:
- 无符号数判断依赖进位标志
CF、零标志ZF,对应JA(高于跳转)、JB(低于跳转)等指令 - 有符号数判断依赖符号标志
SF、溢出标志OF、零标志ZF,对应JG(大于跳转)、JL(小于跳转)等指令
注意:不需要手动将补码转换为十六进制做无符号规则判断,CPU执行
CMP指令时会自动计算对应标志位,直接调用有符号跳转指令即可得到正确结果。
三个有符号数取最大值NASM代码示例
以下为32位Linux环境下的可运行实现:
section .data num1 dd -8 ; 待比较的第一个有符号数 num2 dd -2 ; 待比较的第二个有符号数 num3 dd 11 ; 待比较的第三个有符号数 max_val dd 0 ; 存储最终最大值 section .text global _start _start: ; 初始化最大值为第一个数 mov eax, [num1] ; 比较第一个数和第二个数 cmp eax, [num2] jg check_third ; 若当前最大值大于第二个数,直接比较第三个数 mov eax, [num2] ; 否则更新最大值为第二个数 check_third: cmp eax, [num3] jg save_res ; 若当前最大值大于第三个数,直接保存结果 mov eax, [num3] ; 否则更新最大值为第三个数 save_res: mov [max_val], eax ; 系统调用退出程序 mov ebx, 0 mov eax, 1 int 0x80
如果是8位/16位有符号数比较,仅需将对应寄存器替换为al/ax、变量定义改为db/dw即可,判断逻辑完全一致。
常用有符号数条件跳转指令说明
JG/JNLE:大于(不小于等于)则跳转,满足(SF == OF) && ZF == 0时触发JGE/JNL:大于等于(不小于)则跳转,满足SF == OF时触发JL/JNGE:小于(不大于等于)则跳转,满足SF != OF时触发JLE/JNG:小于等于(不大于)则跳转,满足(SF != OF) || ZF == 1时触发JE/JZ:等于则跳转,无符号/有符号场景通用
内容的提问来源于stack exchange,提问作者ONamaeWa
相关产品推荐
相关产品推荐

