x86汇编实现strcmp模拟函数异常:误判首字符串更大
汇编实现strcmp的错误排查与修复
问题定位
你的程序能正确判断字符串相等,但所有不等场景都误判为第一个字符串更大,核心问题出在以下几点:
1. 参数传递顺序完全颠倒
在main中调用strcmp时,你先入栈first+2,再入栈second+2,但x86汇编的栈是先进后出结构,这导致strcmp函数读取到的参数顺序完全相反:
si = [bp+4]实际指向的是second+2di = [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
相关产品推荐
相关产品推荐

