int strncmp(const char *cs, const char *ct, size_t count)
{
int res;
int d0, d1, d2;
asm volatile("1:\tdecl %3\n\t"
"js 2f\n\t"
"lodsb\n\t"
"scasb\n\t"
"jne 3f\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n"
"2:\txorl %%eax,%%eax\n\t"
"jmp 4f\n"
return 0
"3:\tsbbl %%eax,%%eax\n\t"
"orb $1,%%al\n"
"4:"
: "=a" (res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
: "1" (cs), "2" (ct), "3" (count)
: "memory");
}
移动串指令: MOVSB、MOVSW、MOVSD ;从 ESI -> EDI; 执行后, ESI 与 EDI 的地址移动相应的单位
比较串指令: CMPSB、CMPSW、CMPSD ;比较 ESI、EDI; 执行后, ESI 与 EDI 的地址移动相应的单位
扫描串指令: SCASB、SCASW、SCASD ;依据 AL/AX/EAX 中的数据扫描 EDI 指向的数据, 执行后 EDI 自动变化
储存串指令: STOSB、STOSW、STOSD ;将 AL/AX/EAX 中的数据储存到 EDI 给出的地址, 执行后 EDI 自动变化
载入串指令: LODSB、LODSW、LODSD ;将 ESI 指向的数据载入到 AL/AX/EAX, 执行后 ESI 自动变化
其中的 B、W、D 分别指 Byte、Word、DWord, 表示每次操作的数据的大小单位.
上述指令可以有重复前缀:
REP ECX > 0 时
REPE (或 REPZ) ECX > 0 且 ZF=1 时
REPNE(或 REPNZ) ECX > 0 且 ZF=0 时
;重复前缀可以自动按单位(1、2、4)递减 ECX
sbb指令
DEST ← (DEST – (SRC + CF));
scas指令
AL\AX\EAX − SRC
while(--count>=0)
{
al=*(esi++)
if(al==*(edi++))
if(al==0)
return 0;
else
continue;
else{
eax=-cf;(cf是借位标识符,是由al-*(edi++)比较产生的,如果al>*(edi++),cf=0,return 1;
如果al<*(edi++),那么cf=1,eax=0xffffffff,return -1)
eax|=1;
return eax;
}
}
return 0;