Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.11.12;
Скачать: CL | DM;

Вниз

Встроенный ассемблер   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.05 c
2-1161927953
ГореПрограммер
2006-10-27 09:45
2006.11.12
Колличество элементов динамического массива


2-1161860846
silversmith
2006-10-26 15:07
2006.11.12
Watch показывает неверные значения переменных


1-1159532237
Ангела
2006-09-29 16:17
2006.11.12
Проблема с реестром.


2-1161891637
---------
2006-10-26 23:40
2006.11.12
Оптимизация кода


15-1161891293
Anatoly Podgoretsky
2006-10-26 23:34
2006.11.12
Любителям запуздырить иконку туда где часики посвящается