1#include <asm.inc> 2#include <ksamd64.inc> 3.code64 4#if 0 5 page ,132 6 title strcmp.asm - compare two strings 7;*** 8;strcmp.asm - routine to compare two strings (for equal, less, or greater) 9; 10; Copyright (c) Microsoft Corporation. All rights reserved. 11; 12;Purpose: 13; STRCMP compares two strings and returns an integer 14; to indicate whether the first is less than the second, the two are 15; equal, or whether the first is greater than the second, respectively. 16; Comparison is done byte by byte on an UNSIGNED basis, which is to 17; say that Null (0) is less than any other character (1-255). 18; 19;******************************************************************************* 20include ksamd64.inc 21 subttl "strcmp" 22;*** 23;strcmp - compare two strings, returning less than, equal to, or greater than 24; 25;Purpose: 26; Compares two string, determining their ordinal order. Unsigned 27; comparison is used. 28; 29; Algorithm: 30; int strcmp ( src , dst ) 31; unsigned char *src; 32; unsigned char *dst; 33; { 34; int ret = 0 ; 35; 36; while( ! (ret = *src - *dst) && *dst) 37; ++src, ++dst; 38; 39; if ( ret < 0 ) 40; ret = -1 ; 41; else if ( ret > 0 ) 42; ret = 1 ; 43; 44; return( ret ); 45; } 46; 47;Entry: 48; const char * src - string for left-hand side of comparison 49; const char * dst - string for right-hand side of comparison 50; 51;Exit: 52; AX < 0, 0, or >0, indicating whether the first string is 53; Less than, Equal to, or Greater than the second string. 54; 55;Uses: 56; CX, DX 57; 58;Exceptions: 59; 60;******************************************************************************* 61#endif 62 63#define CHAR_TYPE BYTE 64#define CHAR_PTR BYTE PTR 65#define CHAR_SIZE 1 /* = sizeof CHAR_TYPE */ 66 67#define BLK_TYPE QWORD 68#define BLK_PTR QWORD PTR 69#define BLK_SIZE 8 /* = sizeof BLK_TYPE */ 70 71//PAGE_SIZE = 1000h 72PAGE_MASK = PAGE_SIZE - 1 // mask for offset in MM page 73PAGE_SAFE_BLK = PAGE_SIZE - BLK_SIZE // maximum offset for safe block compare 74 75LEAF_ENTRY_ARG2 strcmp, _TEXT, str1_ptr_byte, str2_ptr_byte 76 77 //OPTION PROLOGUE:NONE, EPILOGUE:NONE 78 79// rcx = src 80// rdx = dst 81 82 sub rdx, rcx 83 test cl, (BLK_SIZE - 1) 84 jz qword_loop_enter 85 86comp_head_loop_begin: 87 movzx eax, CHAR_PTR[rcx] 88 cmp al, CHAR_PTR[rdx+rcx] 89 jnz return_not_equal 90 91 inc rcx 92 93 test al, al 94 jz return_equal 95 96 test cl, (BLK_SIZE - 1) 97 jnz comp_head_loop_begin 98 99qword_loop_enter: 100 101 mov r11, HEX(8080808080808080) 102 mov r10, HEX(0fefefefefefefeff) 103 104qword_loop_begin: 105 lea eax, [edx+ecx] 106 and eax, PAGE_MASK 107 cmp eax, PAGE_SAFE_BLK 108 ja comp_head_loop_begin 109 110 mov rax, BLK_PTR[rcx] 111 cmp rax, BLK_PTR[rdx+rcx] 112 113// mismatched string (or maybe null + garbage after) 114 jne comp_head_loop_begin 115 116// look for null terminator 117 lea r9, [rax + r10] 118 not rax 119 add rcx, BLK_SIZE 120 and rax, r9 121 122 test rax, r11 // r11=8080808080808080h 123 jz qword_loop_begin 124 125return_equal: 126 xor eax, eax // gets all 64 bits 127 ret 128 129return_not_equal: 130 sbb rax, rax // AX=-1, CY=1 AX=0, CY=0 131 or rax, 1 132 ret 133 134LEAF_END strcmp, _TEXT 135end 136