为何基于db定义的8位数组排序汇编代码无法处理大于128的数值?
归并排序处理8位无符号数失效的原因分析
核心问题:有符号比较误用在无符号数值上
x86-64汇编中,cmp指令配合jg(有符号数大于跳转)的逻辑,被错误地用于处理db类型的无符号8位数值(范围0~255)。当数值大于127时,最高位为1,会被CPU当作有符号负数处理,导致比较逻辑完全颠倒,最终排序失效。
具体代码中的问题点
在merge函数的L5代码段中:
L5 : mov al, byte [r11] ; 取右子数组元素到al(8位寄存器) cmp al, byte [r10] ; 比较右元素与左元素 jg L3 ; 若右元素"大于"左元素,跳转到L3取左元素
- 当右元素是128(二进制
10000000)时,作为有符号数会被解析为-128,此时和任何小于128的正数(比如64,二进制01000000)比较,-128会被判定为小于64,jg不会触发,代码会错误地将128优先放入排序数组,而非更小的64。 - 所有大于127的数值都会被当作负数,在有符号比较中被判定为小于任何正数,导致排序结果完全错误。
修复方案
将数值比较相关的有符号跳转指令替换为无符号版本:
- 把
jg L3替换为ja L3(ja是无符号数大于跳转,对应无符号数的比较逻辑)。
补充说明
代码中索引相关的比较(比如cmp r8, rdx配合jg L4)不受影响,因为索引都是非负的64位整数,有符号和无符号比较的结果一致。只有8位数值的比较需要修正为无符号逻辑。
内容的提问来源于stack exchange,提问作者user25004318
相关产品推荐
相关产品推荐

