Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1210090413
TStas
2008-05-06 20:13
2008.06.08
Как написать опережающее объявления класса?


15-1209105904
Vlad Oshin
2008-04-25 10:45
2008.06.08
ScreenShot, размер большой, а нужен маленький . Как?


2-1210977985
Tomn
2008-05-17 02:46
2008.06.08
ImageList &amp; StringGrid


15-1209030623
TUser
2008-04-24 13:50
2008.06.08
X-сервер для ХР


15-1208258501
Kostafey
2008-04-15 15:21
2008.06.08
Размышления о докуметировании структуры БД





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский