Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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.065 c
2-1162152048
md
2006-10-29 23:00
2006.11.12
ошибочка вышла


15-1161842790
kan
2006-10-26 10:06
2006.11.12
кодировка в PHP


3-1158151719
DBLookupComboBox
2006-09-13 16:48
2006.11.12
и хранимая процедура


2-1161895101
aleko
2006-10-27 00:38
2006.11.12
сохранение файла в БД


3-1158136563
Officeman
2006-09-13 12:36
2006.11.12
Как передать русский? (/upload.php?name= мама мыла раму )





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский