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

x86汇编实现strcmp模拟函数异常:误判首字符串更大

汇编实现strcmp的错误排查与修复

问题定位

你的程序能正确判断字符串相等,但所有不等场景都误判为第一个字符串更大,核心问题出在以下几点:


1. 参数传递顺序完全颠倒

在main中调用strcmp时,你先入栈first+2,再入栈second+2,但x86汇编的栈是先进后出结构,这导致strcmp函数读取到的参数顺序完全相反:

  • si = [bp+4] 实际指向的是second+2
  • di = [bp+6] 实际指向的是first+2
    相当于你一直在比较second和first,而非预期的first和second。

2. 返回值AX的高8位未初始化

当字符不等时,你执行sub al, bl计算差值,但ah寄存器的内容是未初始化的随机值,导致整个ax寄存器的结果不符合有符号数判断逻辑:
比如比较"a"和"b"时,al=0x61,bl=0x62,sub al, bl得到0xFF(有符号数-1),但如果ah=0x00,ax=0x00FF会被识别为正数255,最终误判为第一个字符串更大。

3. 循环终止条件的冗余逻辑

continue标签后的cmp al, 0判断的是上一次相等的字符值,逻辑冗余且容易混淆,建议直接在循环开头判断字符是否为结束符。


修复后的完整关键代码

修正后的strcmp函数

strcmp proc
  push bp
  mov bp, sp
  
  mov si, [bp+6]  ; 读取第一个参数:first字符串起始地址
  mov di, [bp+4]  ; 读取第二个参数:second字符串起始地址
  
compare_loop:
  mov al, [si]
  mov bl, [di]
  cmp al, bl
  jne compare_done  ; 字符不等,跳转到计算差值
  cmp al, 0         ; 字符相等且是结束符,说明两字符串完全相等
  je equal_done
  inc si
  inc di
  jmp compare_loop
  
compare_done:
  xor ah, ah        ; 清零AH,确保AX是完整的16位有符号差值
  sub al, bl        ; AX = first_char - second_char
  pop bp
  ret
  
equal_done:
  xor ax, ax        ; 返回0表示两字符串相等
  pop bp
  ret
strcmp endp

修正main中的参数入栈顺序

; 按右到左顺序入栈参数:先入栈second,再入栈first
push offset second + 2
push offset first + 2
call strcmp

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 20:57:10