Во втором варианте можно дальше пойти:
Spoiler:
Code: Select all
cmp byte [eax+3], 0
; ..............................
cmp byte [eax+255], 0
Если точно известно, сколько памяти выделено под строку(например, выделено 4K), то можно смело читать dword за один раз. Примерно так делается, например, в libxds, которая идёт вместе с XDS Modula-2/Oberon-2 compiler.
Первый вариант — наверное, первое, что приходит в голову
Я примерно так же сделал в kernel32, которая используется в PELoad.
lstrlenA, lstrlenW:
Spoiler:
Code: Select all
;**********************************************************************************
lstrlenA: ;////////////////////////////////////////////////////////////////////////
;**********************************************************************************
%define lpString [esp + 4 +1*4] ; null-terminated string to be checked
push edi
mov edi, lpString
xor ecx, ecx
dec ecx
xor al, al
repne scasb
not ecx
dec ecx
mov eax, ecx
pop edi
ret 4
%undef lpString
align 16
;**********************************************************************************
lstrlenW: ;////////////////////////////////////////////////////////////////////////
;**********************************************************************************
%define lpString [esp + 4 +1*4] ; null-terminated string to be checked
push edi
mov edi, lpString
xor ecx, ecx
dec ecx
xor ax, ax
repne scasw
not ecx
dec ecx
mov eax, ecx
pop edi
ret 4
%undef lpString
Я удивился, когда потом обнаружил почти то же самое в исходниках
HX DOS Extender.
Но там не всё так хорошо, как могло быть.
Например lstrcatA.
У меня:
Spoiler:
Code: Select all
;**********************************************************************************
lstrcatA: ;////////////////////////////////////////////////////////////////////////
;**********************************************************************************
%define lpString1 [esp + 4 +2*4] ; first null-terminated string
%define lpString2 [esp + 8 +2*4] ; null-terminated string to be added
push esi
push edi
mov esi, lpString2
xor ecx, ecx
xor eax, eax
mov edi, esi
dec ecx
repne scasb
mov edx, ecx
mov edi, lpString1
repne scasb
dec edi
not edx
mov eax, lpString1
mov ecx, edx
shr ecx, 2
rep movsd
mov ecx, edx
and ecx, 3
rep movsb
pop edi
pop esi
ret 8
%undef lpString1
%undef lpString2
У Japheth:
Spoiler:
Code: Select all
lstrcatA proc uses esi edi string1:ptr byte,string2:ptr byte
xor eax,eax
mov ecx,-1
mov edi,string2
repne scasb
push ecx
mov edi,string1
repne scasb
dec edi
pop ecx
not ecx
mov esi,string2
shr ecx,1
rep movsw
adc ecx,ecx
rep movsb
mov eax,string1
ret
lstrcatA endp
Первый вариант с
rep movsd, конечно будет быстрее, чем второй с
rep movsw. Я привёл часть исходника из v2.16, stable. Сейчас также доступна v2.17, release candidate, может быть, там уже что-то изменилось.