Форум: "Начинающим";
Текущий архив: 2008.06.08;
Скачать: [xml.tar.bz2];
ВнизФункция на ассемблере Найти похожие ветки
← →
Антенна (2008-05-18 17:43) [0]Есть функция которая складывает два двоичных числа суммой по модулю два и считает количество единиц в получившемся числе:
В переменных 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;
Но считает не правильно, не пойму в чём дело, помогите пожалуйста оформить функцию.
← →
Anatoly Podgoretsky © (2008-05-18 17:51) [1]> Антенна (18.05.2008 17:43:00) [0]
Ничего из заявленого функция не делает.
← →
Антенна (2008-05-18 17:59) [2]Anatoly Podgoretsky, а ты получше подумай...
← →
guav © (2008-05-18 18:10) [3]Символы строки имеют меньше размер чем размер регистра. ebx менять неьзя.
Нечестно используются сторки - для не-const надо учитывать рефкаунтинг, хотя в данном случае они просто используются как const, поэтому тут лучше добавить этот самый const.
От ассемблерности очевидной выгоды нет, кроме того ассемблерный код не оптимален.
Советую просто оптимизировать паскалевскую функцию.
← →
Renegat (2008-05-18 18:52) [4]А что если ети двоичные числа передавать не через строки, а в массивах, разбитыми на DWORD-ы? Это даст улучшение и по памяти, и по скорости! Нужно будет просто брать последовательно DWORD первого и второго числа, складывать их и анализировать CF - если не сброшен, значит к следующей сумме добавляем 1. А потом проходимся по результату с помощью BT. Ъ?
← →
Сергей М. © (2008-05-18 19:53) [5]
> а ты получше подумай
Думать следует тебе.
← →
Sha © (2008-05-18 20:50) [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;
← →
Slym © (2008-05-19 05:48) [7]
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-19 09:40) [8]> Slym © (19.05.08 05:48) [7]
Можно пойти еще дальше :)
1) длину строки брать по смещению -4,
2) обраьатывать по 4 символа за раз,
3) испоьзовать вместо сравнения xor,
4) зная, что в строка могут быть только два вида символоа,
отличающихся на 1, вычислять новое значение счетчика сразу,
без всяких проверок на совпадение
← →
Slym © (2008-05-19 12:21) [9]Sha © (19.05.08 9:40) [8]
обраьатывать по 4 символа за раз
прально... развертку циклоф нужно делать в первую очередь
← →
Sha © (2008-05-19 14:22) [10]> Slym © (19.05.08 12:21) [9]
я не развертку имел ввиду, а че-нить типа
mov edx,[esi+ecx]
xor edx,[edi+ecx]
← →
Sha © (2008-05-19 16:23) [11]Вот так примерно (вовращается -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;
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2008.06.08;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.069 c