Форум: "Прочее";
Текущий архив: 2006.11.12;
Скачать: [xml.tar.bz2];
ВнизВстроенный ассемблер Найти похожие ветки
← →
partizan (2006-10-24 05:38) [0]Пытаюсь написать на асме длинную арифметику (сложение для начала).
Вот, что пока получилось(на 1-цу переноса пока забил, но в этом суть):
procedure summ(a,b,c:pointer;n:integer);
label end_cycl,start_cycl,
begin
asm
mov ecx,n;
xor esi,esi;
xor eax,eax;
start_cycl:
//begin cycl
jecxz end_cycl;
mov edx,a;
mov eax,[edx][esi];
mov edx,b;
add eax,[edx][esi];
mov edx,c;
mov [edx][esi],eax;
add esi,4;
dec ecx;
jmp start_cycl;
//end cycl
end_cycl:
xor eax,eax;
end;
end;
Пара вопросов:
1)(основной):
Как можно упростить эту запись:
mov edx,a;
mov eax,[edx][esi];
Если б это было на обычном ассемблере, это записывалось бы просто
mov eax,a[esi];
Но в обычном - a - это метко ячейки памяти, где начинается массив (константа), а у меня - это переменная, которая этот адресс содержит.
Такая запись тоже не канает:
mov eax,[a][esi];
Может можно обьявить как-то константу с этим адресом?
Тут a- адрес начала масива
← →
partizan (2006-10-24 05:39) [1]Но последнюю строчку прошу забить, отправил пост раньше времени.
← →
partizan (2006-10-24 06:42) [2]Пока нашел такое решение проблемы:
type tlong =
record
case byte of
0: (dg:array[0..$3ff] of integer);
1: (x:integer);
end;
Переменные a,b,c - глобальные, типа tlong,
и тогда вместо:mov edx,a;
mov eax,[edx][esi];
записывается:mov eax,a.x[esi]
← →
Ketmar © (2006-10-24 06:45) [3]знать не знаю, что такое "обычный ассемблер". вариант [esi+a] -- никак?
кстати, тебе не говорила справка, что ESI, EDI (и EBX желательно) надо бережно сохранять и не менее бережно потом восстанавливать?
ещё мне очень интересно, зачем передавать в процедуру a, b и с, если их радостно выкидывают нафиг? пардон, но если calling convention -- register (а по-умолчанию так и есть), то первые три параметра попадают в edx, eax и ecx. о чём та же справка охотно расскажет.
далее. связка jmp/jecxz -- это зачем? один jecxz в самом начале -- чтобы с нулевой длиной справиться, и один jnz в конце. всё.
зачем обнулять eax по выходу, если это процедура?
точки с запятыми -- лишние. не мешают, но напрочь лишние.
зыж ах, да. begin/end делают пролог и эпилог. тормоз. потому и calling convention можно игнорировать. выкинуть это, начинать сразу с asm.
локальные метки можно делать так:@lbl:
-- тогда их не надо объявлять.
вердикт: в представленом виде код далёк от оптимального. проще сделать на чистом паскале и отдать оптимизатору -- пусть старается.
ззыж надеюсь, пост будет воспринят не как ушат помоев, а как руководство к действию. %-)
← →
partizan (2006-10-24 07:00) [4]
> ззыж надеюсь, пост будет воспринят не как ушат помоев, а
> как руководство к действию. %-)
Будет, воспринят, как руководство к действию, кроме пункта
> проще сделать на чистом паскале и отдать оптимизатору
Спасибо за советы.
вариант [esi+a] подходит, но тоже переменные надо делать глобальными.
А так, чтоб в процедуру передавалисть именно ссылки на массивы, никак?
← →
Ketmar © (2006-10-24 07:24) [5]>[4] partizan 24-Oct-2006, 07:00
>вариант [esi+a] подходит, но тоже переменные надо делать
>глобальными.
смотри мои замечания по calling convention. убрать пролог и эпилог -- тогда указатели сразу попадут в регистры. и одним дорогим (да и лишним) разыменованием станет меньше. останется только "перетусовать" указатели в удобные места (не забыв сохранить ESI, EDI и EBX %-).
индексы вообще можно (и нужно) сразу превратить в адреса. тогда появится возможность использовать lodsd и stosd.
>А так, чтоб в процедуру передавалисть именно ссылки на
>массивы, никак?(var arg)
даст как раз указатель на что угодно. в том числе и на массив.
зыж и оно тебе надо -- на асме это ваять? сплошной геморрой. а это ты ещё не дошёл до деления, например...
← →
partizan (2006-10-24 08:19) [6]Деление состоит из умножений и вычитаний, его можно уже на паскале писать, с использованием ассемблерных умножения и сложения.
А можно немного подробнее насчет
> (var arg) даст как раз указатель на что угодно. в том числе
> и на массив
и
> индексы вообще можно (и нужно) сразу превратить в адреса.
> тогда появится возможность использовать lodsd и stosd
← →
Ketmar © (2006-10-24 08:34) [7]>[6] partizan 24-Oct-2006, 08:19
>А можно немного подробнее
куда уж подробней-то? %-(
>> (var arg)
аргументы так описываем. вместо(a: Pointer)
. и вызываем примерно как Proc(a[0]);
>> индексы вообще можно (и нужно) сразу превратить в адреса.
а здесь-то что неясно? ну вот:mov edx,arr
mov ecx,10
mov eax,[edx+ecx*4]
...
inc ecx
mov eax,[edx+ecx*4]
это -- индексация.
mov esi,a
add esi,10*4
lodsd
...
lodsd
это -- превращение индекса в адрес. заодно, кстати, регистр освободили.
зыж есть подозрение, что автор темы зачем-то начал писать на ассемблере, ни разу до этого ничего на нём не делав. иначе пояснить перенос паскалевских конструкций "один-в-один" я не могу. это опять не пинок, а намёк.
← →
partizan (2006-10-24 08:42) [8]Сспасибо, будем разбиратся
← →
partizan (2006-10-24 08:52) [9]Да, кстати, если аргументы описывать через var (porc(var arg:integer)), то команда mov eax,a помещает в регистр адресс переменной аrg, а не значение, тоесть тоже самой, что передавать указатель
← →
Ketmar © (2006-10-24 09:36) [10]>[9] partizan 24-Oct-2006, 08:52
ты не поверишь, но описание типа "var xxx[пофиг что]" -- это и есть передача по ссылке. о чём тоже недвусмыслено повествует всезнающая справка. в моём варианте ещё проще -- тип вообще не указан (потому что он здесь -- не пришей Delphi ++).
я тебе ещё один секрет скажу: описание типа "const xxx" и "out xxx" -- это тоже ссылки. о чем написано... ага, в ней сАмой. %-)
%-)
← →
Alex Konshin © (2006-10-24 13:18) [11]
> Ketmar © (24.10.06 09:36) [10]
Насчет const ты погорячился.
PS: Вообще занятно, я тут тоже как раз длинную арфметику реализую. Мне для реализации RSA надо. Собственно арифметика вплоть до деления уже сделана :).
Кстати, на http://algolist.manual.ru/ ошибка в описании алгоритма деления (в подборе очередной цифры). Кнут рулит, но у него не совсем оптимальная нормализация предлагается, я сделал проще - вычисляю сдвиг влево, чтобы сташий бит делителя стал единицей. Дешево и сердито.
← →
Alex Konshin © (2006-10-24 13:29) [12]Это сложение для партизана:
digit - это в моем случае 32-bit.
//-------------------------------------------------------------
// Computes a := b + c.
procedure NN_Add( a, b, c : PDigits; digits : LongWord );
asm
push esi
push edi
mov esi,edx // esi = b
mov edi,eax // edi = a
mov edx,ecx // edx = c
mov ecx,digits
test ecx,ecx
jz @@exit
clc
@@next:
lodsd
adc eax,[edx]
stosd
lea edx,[edx+4]
loop @@next
@@exit:
pop edi
pop esi
end;
← →
Anatoly Podgoretsky © (2006-10-24 13:50) [13]Слишком много ошибок в исходном коде, чтобы его обсуждать. Ошибки начинаются со второй строки и идут далее.
← →
partizan (2006-10-24 14:49) [14]
> лишком много ошибок в исходном коде, чтобы его обсуждать.
> Ошибки начинаются со второй строки и идут далее.
Надеюсь имеется ввиду мой код, приведенный в самом начале, а не код от
Alex Konshin ©, за который ему огромное спасибо?
← →
partizan (2006-10-24 15:17) [15]2 Alex Konshin:
Ещераз спасибо.
Попытался разобратся в приведенном коде
Поправте, где я не прав:
1) lodsd загружает в eax значение из ячейки, адрес которой в esi
2) sotsd загружает значение eax в ячейку, адрес которой edi
3) строчку lea edx,[edx+4] по-моему надо заменить на lea edx,edx+4
4) приведенный код складывает числа из массивов b и с в массив а
← →
Anatoly Podgoretsky © (2006-10-24 15:25) [16]
> Надеюсь имеется ввиду мой код, приведенный в самом начале
Естественно твой, вот его и не стоит рассматривать, а если рассматривать, то за основу брать код от Коншина.
← →
Ketmar © (2006-10-24 17:09) [17]>[11] Alex Konshin(c) 24-Oct-2006, 13:18
>Насчет const ты погорячился.
???procedure a (const n);
я же не сказал, что в любом случае. %-)
>[15] partizan 24-Oct-2006, 15:17
>3) строчку lea edx,[edx+4] по-моему надо заменить на lea
> edx,edx+4
а по-моему, кто-то с ассемблером не дружит.
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2006.11.12;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.043 c