![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Функция на ассемблере
Антенна © (2008-05-18 17:43:00)Есть функция которая складывает два двоичных числа суммой по модулю два и считает количество единиц в получившемся числе:
В переменных s и s1 передаётся двоичное n-разрядное число, j - накапливает количество единиц получившихся в новом числе при сложении s и s1 суммой по модулю 2.
function RasD1(s,s1:string):integer;
var
i,j:integer;
begin
j:=0;
for i:=1 to n do
if s[i]<>s1[i] then inc(j);
Result:=j;
end;
Хочу переписать эту функцию языке встроенного ассемблера, пишу:
function RasD1(s,s1:string):integer;
var
i,j:integer;
begin
j:=0;
asm
mov ecx,n
@M1:
mov eax,s[ecx]
mov ebx,s1[ecx]
cmp eax,ebx
jz @M2
inc(j)
@M2:
loop @M1
end;
Result:=j;
end;
Но считает не правильно, не пойму в чём дело, помогите пожалуйста оформить функцию.
Sha (2008-05-19 16:23:00) [1]Вот так примерно (вовращается -1, если символы различаются не в младшем бите)
function XorStrings(s1, s2: string): integer;
asm
push ebx
push esi
push edi
xor esi,esi
test eax, eax
jz @zerolen1
mov esi, [eax-4]
@zerolen1:
xor edi,edi
test edx, edx
jz @zerolen2
mov edi, [edx-4]
@zerolen2:
cmp esi, edi
je @leneq
@error:
or eax,-1
jmp @done
@leneq:
test esi, esi
jnz @nzerolen
xor eax, eax
jmp @done
@nzerolen:
sub esi, 1
or ecx, -1
test esi, 2
jnz @last4bytes
mov ecx, $0000ffff
@last4bytes:
and esi, -4
mov edi, [eax+esi]
xor edi, [edx+esi]
and edi, ecx
xor ecx, ecx
xor ebx, ebx
jmp @test
@loop:
sub esi, 4
mov edi, [eax+esi]
xor edi, [edx+esi]
@test:
test edi, $fefefefe
jnz @error
add ecx, edi
test esi, $7c
jnz @loop
mov edi, ecx
shr ecx, 8
add ecx, edi
mov edi, ecx
shr ecx, 16
add ecx, edi
and ecx, $000000FF
add ebx, ecx
xor ecx, ecx
test esi, esi
jg @loop
@ret:
mov eax, ebx
@done:
pop edi
pop esi
pop ebx
end;
Sha (2008-05-19 14:22:00) [2]> Slym © (19.05.08 12:21) [9]
я не развертку имел ввиду, а че-нить типа
mov edx,[esi+ecx]
xor edx,[edi+ecx]
Slym (2008-05-19 12:21:00) [3]Sha © (19.05.08 9:40) [8]
обраьатывать по 4 символа за раз
прально... развертку циклоф нужно делать в первую очередь
Sha (2008-05-19 09:40:00) [4]> Slym © (19.05.08 05:48) [7]
Можно пойти еще дальше :)
1) длину строки брать по смещению -4,
2) обраьатывать по 4 символа за раз,
3) испоьзовать вместо сравнения xor,
4) зная, что в строка могут быть только два вида символоа,
отличающихся на 1, вычислять новое значение счетчика сразу,
без всяких проверок на совпадение
Slym (2008-05-19 05:48:00) [5]
function RasD_Asm(const s1,s2:string):integer;
asm
PUSH ESI
PUSH EDI
MOV ESI, S1
MOV EDI, S2
call System.@LStrLen
TEST EAX, EAX
JZ @@exit
mov ECX, EAX
XOR EAX, EAX
@@loop:
MOV DL, [ESI+ECX-1]
CMP DL, [EDI+ECX-1]
JZ @@skip
INC EAX
@@skip:
dec ECX
jnz @@loop
@@exit:
POP EDI
POP ESI
end;
Anatoly Podgoretsky © (18.05.08 17:51) [1]
Ничего из заявленого функция не делает.
+1
Sha (2008-05-18 20:50:00) [6]> Антенна (18.05.08 17:43)
Поразрядное сложение двоичных чисел по модулю 2
с последующим подсчетом единичных разрядов (ух :-))
function XorBitCount(i1, i2: integer): integer;
begin;
i2:=i2 xor i1;
i1:=0;
while i2<>0 do begin;
i2:=i2 and (i2-1);
inc(i1);
end;
Result:=i1;
end;
Сергей М. (2008-05-18 19:53:00) [7]
> а ты получше подумай
Думать следует тебе.
Renegat (2008-05-18 18:52:00) [8]А что если ети двоичные числа передавать не через строки, а в массивах, разбитыми на DWORD-ы? Это даст улучшение и по памяти, и по скорости! Нужно будет просто брать последовательно DWORD первого и второго числа, складывать их и анализировать CF - если не сброшен, значит к следующей сумме добавляем 1. А потом проходимся по результату с помощью BT. Ъ?
guav (2008-05-18 18:10:00) [9]Символы строки имеют меньше размер чем размер регистра. ebx менять неьзя.
Нечестно используются сторки - для не-const надо учитывать рефкаунтинг, хотя в данном случае они просто используются как const, поэтому тут лучше добавить этот самый const.
От ассемблерности очевидной выгоды нет, кроме того ассемблерный код не оптимален.
Советую просто оптимизировать паскалевскую функцию.
Антенна (2008-05-18 17:59:00) [10]Anatoly Podgoretsky, а ты получше подумай...
Anatoly Podgoretsky (2008-05-18 17:51:00) [11]> Антенна (18.05.2008 17:43:00) [0]
Ничего из заявленого функция не делает.