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

x86_64汇编实现strcmp为何出现相等判断顺序相关异常?

x86_64汇编实现strcmp的返回值比较异常问题

问题现象

用x86_64汇编实现简易版my_strcmp后,与C库原生strcmp对比出现以下异常:

  • 两者返回值打印结果看似一致(例如均为-11)
  • 条件(strcmp(s1,s2) == my_strcmp(s1,s2))判断为假,而my_strcmp(s1,s2) == strcmp(s1,s2)却为真
  • 用C语言实现相同逻辑的版本无此问题

编译步骤与输出差异

编译命令

nasm -f elf64 -g my_strcmp.s -o my_strcmp_assembly.o
gcc -c my_strcmp.c
gcc main.c my_strcmp.o -o c_version.out
gcc main.c my_strcmp_assembly.o -o asm_version.out
./c_version.out && ./asm_version.out

输出对比

C版实现(符合预期)

a == b
strcmp return value is -11
ft_strcmp retun value is -11
OK1
OK2

汇编版实现

a == b
strcmp return value is -11
ft_strcmp retun value is -11
OK2

使用环境:gcc 11.4.0、nasm 2.15.05

问题根源

这是因为汇编实现未遵循x86_64 System V ABI的返回值约定:

  1. C标准库的strcmp返回int类型(32位有符号整数),会自动符号扩展到64位的rax寄存器中(例如-11的64位表示为0xfffffffffffffff5)。
  2. 你的汇编实现仅将字符差值存入8位的al寄存器就直接返回,未将其符号扩展到整个64位rax,导致rax的高56位保留了随机垃圾值(例如差值-11的8位是0xf5,若高位为0则rax值为0x00000000000000f5,即十进制245)。
  3. 这种不符合约定的返回值触发了C语言的未定义行为,导致比较顺序不同时结果异常。

解决方案

在汇编代码中,计算出字符差值后,使用cdqe指令将8位差值符号扩展到整个64位rax寄存器,确保返回值符合ABI约定。

示例修正后的核心汇编逻辑:

global my_strcmp

my_strcmp:
    ; rdi = s1, rsi = s2
.loop:
    mov al, byte [rdi]
    cmp al, byte [rsi]
    jne .diff
    test al, al
    je .equal
    inc rdi
    inc rsi
    jmp .loop
.diff:
    sub al, byte [rsi] ; 计算s1[i] - s2[i]
    cdqe               ; 将8位有符号数扩展到64位rax
    ret
.equal:
    xor eax, eax       ; 返回0,自动扩展到rax
    ret

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 14:35:56