Вниз
Скачать: CL | DM;

Функция на ассемблере   Найти похожие ветки 

← →
Антенна   (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 вся ветка

Скачать: CL | DM;



Память: 0.48 MB
Время: 0.013 c
2-1210854738
Tommy
2008-05-15 16:32
2008.06.08
MySQL и Delphi


4-1190539420
Jeeb
2007-09-23 13:23
2008.06.08
Список модемов Windows XP


15-1208980904
MM_ASH
2008-04-24 00:01
2008.06.08
Как сделать свой проект


3-1199432867
Ganda
2008-01-04 10:47
2008.06.08
сортировка символьного поля как целочисленное


15-1209048184
i
2008-04-24 18:43
2008.06.08
проблемы с win2003 r2..




   Наверх