Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2011.08.07;
Скачать: [xml.tar.bz2];

Вниз

Копирование масссива на ассемблере BASM (пара вопросов)   Найти похожие ветки 

 
Гость   (2011-04-06 16:39) [0]

Тренируюсь писать на ассемблере... Получилось вот что... Собственно несколько вопросов (в комментариях)...

procedure MemCopy_Alpha(_to, _from: Pointer; _cnt: Integer);
begin // почему обязательно помещать эту ассемблерную вставку в "begin/end"?
asm
     mov ecx, _cnt
     mov edx, _to // не нужно помещать второй операнд в квадратные скобки?
     mov eax, _from
     // align 16 // BASM чтот не знает что это... хотя я тоже... :D
     @next:
     mov ebx, [eax]
     mov [edx], ebx // а сразу "[eax]->[edx]" вообще совсем никак не предусмотрено, да? :(
     add edx, 4
     add eax, 4
     sub ecx, 4
     jnz @next // почему перед этим не надо было "cmp" делать?
     end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var a, b: Int64;
begin
a:=4000000000;
b:=6767676767;
ShowMessage("a = "+IntToStr(a)+";"#10"b = "+IntToStr(b)+";");
MemCopy_Alpha(@a, @b, SizeOf(Int64)); // просто для "икспирименту", проверить работает ли оно вообще...
ShowMessage("a = "+IntToStr(a)+";"#10"b = "+IntToStr(b)+";");
Button2.Click; // почему-то вылетает тут... даже если в этом обработчике пусто... а вот если закомментировать Asm_CopyMemory_v1, то сразу всё в порядке...
end;


 
Гость   (2011-04-06 16:42) [1]

Опечатка - Asm_CopyMemory_v1 старое название MemCopy_Alpha...
Оно мне не нравилось, переименовал потом...


 
Игорь Шевченко ©   (2011-04-06 16:45) [2]


> а сразу "[eax]->[edx]" вообще совсем никак не предусмотрено,
>  да? :(


не предусмотрено


> // почему перед этим не надо было "cmp" делать?


sub выполняет те же действия над флагами, что и cmp


 
Игорь Шевченко ©   (2011-04-06 16:46) [3]


>
> MemCopy_Alpha(@a, @b, SizeOf(Int64)); // просто для "икспирименту",
>  проверить работает ли оно вообще...


RTFM: calling conventions
или ставь своей ассемблерной процедуре модификатор stdcall


 
Дмитрий Белькевич   (2011-04-06 17:15) [4]


> begin // почему обязательно помещать эту ассемблерную вставку
> в "begin/end"?


Откуда ж компилятору знать, что у тебя там только ассемблерная вставка, и ничего больше? Если только - то так и пиши: procedure MemCopy_Alpha(_to, _from: Pointer; _cnt: Integer); assembler;


> а сразу "[eax]->[edx]" вообще совсем никак не предусмотрено,
>  да? :(


Вот такой он, x86, плохой :)


> почему перед этим не надо было "cmp" делать?


Нужно знать, что конкретно cmp делает. Что бы понять, где он нужен, а где - нет. Это если есть интерес разобраться а не просто код копипастить из учебников.


 
Slym ©   (2011-04-08 14:12) [5]

1. почему обязательно помещать эту ассемблерную вставку в "begin/end"?
ты пользуешь EBX и не сохраняешь его предыдущее состояние, begin/end - делает это за тебя
2. а сразу "[eax]->[edx]" вообще совсем никак не предусмотрено, да? :(
нет операнд (память, память) был бы слишком длинным
3. jnz @next // почему перед этим не надо было "cmp" делать?
CMP почти тотже sub только без сохранения результата это раз!
А ВОТ ТУТ БЕСКОНЕЧНЫЙ ЛУП!!! если _cnt не кратен 4 (sub ecx, 4) это два!
MemCopy_Alpha(@a, @b, SizeOf(Int64)-1);


 
Slym ©   (2011-04-08 14:18) [6]

от бегинов избавляемся так

procedure MemCopy_Alpha2(_to{eax}, _from{edx}: Pointer; _cnt{ecx}: Integer);
asm
 push ebx
 @next:
   mov ebx, [edx]
   mov [eax], ebx
   add edx, 4
   add eax, 4
   sub ecx, 4
 jnz @next // почему перед этим не надо было "cmp" делать?
 pop ebx
end;


 
RWolf ©   (2011-04-08 15:28) [7]


>  @next:    mov ebx, [edx]
>    mov [eax], ebx
>    add edx, 4
>    add eax, 4
>    sub ecx, 4
>  jnz @next

rep movsd не проще?


 
Slym ©   (2011-04-11 05:46) [8]

RWolf ©   (08.04.11 15:28) [7]
проще

проще, но медленнее чем тут http://fastcode.sourceforge.net/


 
Гость   (2011-04-27 16:57) [9]

Спасибо всем!) Простите что долго не появлялся, интернета не было...((

Про stdcall знаю, пробовал дописывать, но он не дал видимых эффектов...
Учебника у меня нету, по примерам из VCL и интернета разбираю методом "тыка"...) Смотрел исходник CopyMemory дельфийского - там какая-то жуть, хотя почему-то быстрее работает...
Бесконечного цикла не было - данные кратны 4 были... Но потом доделал копирование хвоста (если есть) через rep movsb (на случай данных произвольных размеров)...
2 Slym: а я ж не только этот регистр использую, значить все сохранять? Кстати если так сделать то на Button2.Click; уже не вылетает...
2 RWolf: проще, но почему-то медленее...

А так что с "align 16"?


 
Rouse_ ©   (2011-04-27 22:20) [10]

За нетрадиционное юзание EBX вместо ESI+EDI, предназначенных для работы с цепочками, побьют палками...


 
Rouse_ ©   (2011-04-27 22:25) [11]

Вообще лучше начинать с Юрова или Марека.
Марек есть у меня на сайте: http://rouse.drkb.ru/books.php#marek
Юрова чей-то я не выложил, но по использованию регистров глянь тут: http://www.piter-press.ru/attachment.php?barcode=978546900003&at=exc&n=0


 
Германн ©   (2011-04-28 02:19) [12]


> Rouse_ ©   (27.04.11 22:20) [10]
>
> За нетрадиционное юзание EBX вместо ESI+EDI, предназначенных
> для работы с цепочками, побьют палками...
>

Не. Скорее просто проигнорируют при приёме на работу. :)


 
han_malign   (2011-04-28 10:21) [13]


> rep movsd не проще?
...
> CopyMemory дельфийского - там какая-то жуть, хотя почему-то быстрее работает...

- я не знаю на какой помойке вы нашли свои процессоры,
но на Core 2 - rep movsb работает на 6,6%(15|16) быстрее system.move/CopyMemory(и на 1% медленнее чем rep movsd)...

(Профиль - 10 x 512 Мб)

> проще, но медленнее http://fastcode.sourceforge.net/

-  FastMove на SSE, надо признать - в полтора раза(2|3) быстрее чем movsb
(MoveJOH_SSE_10,MoveJOH_SSE2_10,MoveJOH_SSE_10)...
MoveJOH_PAS_10, MoveJOH_IA32_10, MoveJOH_MMX_10 - от system.move - мало отличаются...

Необходимость топорной оптимизации копирования памяти канула в лету в прошлом веке...


 
Sapersky   (2011-04-28 12:25) [14]

За нетрадиционное юзание EBX вместо ESI+EDI, предназначенных для работы с цепочками, побьют палками...

Не. Скорее просто проигнорируют при приёме на работу. :)


Не иначе, работа в Министерстве Обороны, где предназначение всех регистров прямо прописано в уставе.
Кстати, при использовании MMX/SSE довольно часто оказываются свободными eax/edx. Если сделать не по уставу, можно избежать лишних пересылок/push/pop, в целом получится короче и изящнее. Но это, ясное дело, не наш метод...

но на Core 2 - rep movsb работает на 6,6%(15|16) быстрее system.move/CopyMemory

У старых версий Move сделан на как раз REP MOVSD. У новых (с D2006) - вариант из FastCode без спецкоманд, но FastCode затачивался под P4/старые Athlon, так что не исключено, что под C2D он уже не самый быстрый.
И по моим тестам на C2D, если склероз не изменяет, оказалось что зависит от размера блока. На больших (от 2 кб вроде) быстрее старый Move с REP, на мелких новый. Но разница небольшая, что-то вроде тех же 6%.


 
Sapersky   (2011-04-28 12:33) [15]

А так что с "align 16"?

AFAIK, выравнивание кода на 16 байт. Вроде бы выравненный адрес джампа (начало цикла) несколько ускоряет этот цикл, но разница чисто символическая (несколько процентов?).
Дельфи такие вещи не поддерживает, только начало функции выравнивается на 4.


 
Sapersky   (2011-04-28 13:02) [16]

Кстати, при использовании MMX/SSE довольно часто оказываются свободными eax/edx.

Точнее, не надо далеко ходить, в приведённых примерах на eax/edx и сделано, а ebx используется в качестве временного хранилища. Запутали вы меня с "EBX вместо ESI+EDI".


 
Anatoly Podgoretsky ©   (2011-04-28 14:12) [17]


> Гость   (06.04.11 16:39)  

Перед программированием на BASM надо ознакомиться с соглашение об вызовах, об использование и не порче регистров.
Данная процедура не живая, нарушает требования.


 
han_malign   (2011-04-28 18:14) [18]


> У старых версий Move сделан на как раз REP MOVSD.

- дык, там сама оптимизация выражалась в выравнивании на границу DWORD и соответствующее DWORD квантование - на на процессорах с 32-бит шиной данных - давало разительное увеличение производительности...
На системах с 64-бит шиной данных - QWORD квантование FastCode(FPU) - давало преимущество, до тех пор пока DMA-канал память-память - вновь(со времен i8086) не стал быстрым...


 
Игорь Шевченко ©   (2011-04-28 18:33) [19]

han_malign   (28.04.11 18:14) [18]


> до тех пор пока DMA-канал память-память


Казалось бы, причем тут DMA



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2011.08.07;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.002 c
2-1303810026
Палыч
2011-04-26 13:27
2011.08.07
Экспорт графика Tchart


15-1303019199
Inovet
2011-04-17 09:46
2011.08.07
Монеты, посвященные олипиаде в Сочи 2014


2-1279050439
Evgeney
2010-07-13 23:47
2011.08.07
Рамка для вырезания рисунка...


2-1302509942
Максон
2011-04-11 12:19
2011.08.07
StringGrid и таблица Word


2-1304085586
ПростоВася
2011-04-29 17:59
2011.08.07
Как работать с WM_GETTEXT





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