Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

к вопросу о встроенном ассемблере [D7, WinXP]


Sergey Pavl ©   (2002-12-09 13:50:00) 

Допустим у меня массив, состаящий из нескольких миллионов чисел. Над

всеми этими числами нужно провести некоторые математические

преобразования. Чтобы ускорить процесс, можно сделать вычислительный

блок в виде ассемблерной вставки. Но если эту вставку написать в

отдельной функции, то, на сколько я понимаю, при обработке каждого

элемента прийдется вызывать эту функцию. Но ведь программа с блоком

кода, выведенным в отдельную функцию, работает медленнее. Т.е. ввод

ассемблерной вставки с целью повышения скорости обработки массива

сводится на нет. Вот и возникает вопрос, можно ли ввести ассемблерную

вставку внутрь, например, оператора FOR...? Если да, то допустим есть

динамический массив А[i], как передать содержимое i-ого элемента в

регистр eax и как достать потом результат?
И еще маленький вопросик, пусть в нашем массиве шестнадцатиричные

числа, внутри ассемблерной вставки компилятор будет знать, что он

работает с шестнадцатиричным числом, или нужно как-то ему это пояснять?
Если нужно указать, что число шестнадцатиричное, то как это сделать?
Спасибо за предыдущие ответы.


Murtix   (2002-12-11 20:41:00) [1]


const
n = 1000;
var
m : array [0..n]of integer;
i : integer;
begin
//Код Delphi
asm
mov ecx, n
xor ebx, ebx
@Loop :
mov eax, dword ptr m[ebx*4]//по-моему ecx вместо ebx нельзя
//не пришлось бы тратить такты
//но ты все же проверь
inc ebx
mov dword ptr m[ebx], eax
loop @Loop
{в этом примере m[i]->m[i+1], смещение вправо}
end;
end;

почитай доку по асме например: www.wasm.ru,
www.hi-tech.nsys.by // тут же архив ихней рассылки
я в интернет кафе засим информации мало и дельфей рядом нету
не имею возможности проверить
Удачи, направь на мыл если до сих пор этим вопросом интересуешся.


Sha   (2002-12-09 19:55:00) [2]

>вставки кода - в Паскале это было, в Дельфи нет.

Чуть выше я уже все поправил.
Хотел написать следующее:

Внутрь FOR - пожалуйста, а INLINE вставки кода - в Паскале это было, в Дельфи нет.

Но мысли бежали впереди рук - что из этого получилось, вы видели. Sorry.


han_malign   (2002-12-09 16:02:00) [3]

> вставки кода - в Паскале это было, в Дельфи нет.
program Basm;
{$APPTYPE CONSOLE}
uses
Utils;
var w: Longword;
a: array[0..100]of word;
i: integer;
begin
for i:=0 to 100 do a[i]:=Random(65535);
asm
xor EAX,EAX
xor EDX,EDX
end;
for i:=0 to 100 do
asm
mov ebx,i
add ebx,ebx
mov DX,word ptr(a[ebx])
add EAX,EDX
end;
asm
mov w,EAX
end;
writeln(w);
// Insert user code here
end.


Sha   (2002-12-09 15:25:00) [4]

Небольшое замечание:
если используешь присваивания регистрам (кроме eax, ecx, edx)
вне ассемблерной процедуры (как показал andrew), то надо их
предварительно сохранять в начале ассемблерной вставки и
восстанавливать в конце.

Последнюю строку моего предыдущего поста надо читать так:
INLINE вставки кода - в Паскале это было, в Дельфи нет.


Calm   (2002-12-09 14:59:00) [5]


> andrew (09.12.02 14:39)
> Вот так вот можно писать(читать абсолютно также) элементы
> массива.

Если я правильно понял, приведен пример чтения.


andrew   (2002-12-09 14:39:00) [6]

Вот так вот можно писать (читать абсолютно также) элементы массива.

var A : array [1..10] of integer;
Start : pointer;
i : integer;
begin
A[4] := 777;
Start := @A;
asm
mov ebx, Start
mov edi, 3 * 4 // вместо тройки должно быть вычисленное значение номера элемента
mov eax, [ebx + edi] // в eax попадает 777
end;
end;


Calm   (2002-12-09 14:14:00) [7]

Для организации циклов имеется команда Loop.
Можно и без нее. Организовать цикл проблемы нет.


Calm   (2002-12-09 14:13:00) [8]


> Если нужно указать, что число шестнадцатиричное, то как
> это сделать?

Никак.
Слобо поддерживает типизацию данных.
Есть некоторая область памяти, содержащая массив чисел. Но каков размер числа, где заканчивается одно и начинается другое, должен знать программист.
А пересылать очень просто - mov
Например, есть адрес, который ассоциируется с началам массива StartAddress, тогда переслать 2-ое по счету 16-ти разрядное число можно так
move ax, StartAddress+2


Sha   (2002-12-09 14:07:00) [9]

Просто надо в ассемблерную процедуру передать побольше данных
за один раз, тогда и вызывать ее придется реже. Передавай
сразу весь массив.
Внутрь FOR - в Паскале это было, в Дельфи нет.


Separator   (2002-12-09 14:06:00) [10]

Вот что мне понаписали в пятницу, эта функция выдает позицию элемента N в массиве Values, может поможет

function NPos(N: Integer; const Values: array of Integer):integer;
asm
push ebx
mov ebx, edx
@@10:
test ecx, ecx
jl @@40
cmp eax, [edx]
je @@30
add edx, 4
dec ecx
jmp @@10
@@30:
mov eax, edx
sub eax, ebx
shr eax,2
jmp @@50
@@40:
mov eax,-1
@@50:
pop ebx
end;


Наверх

Титульная страница Поиск, карта сайта Написать письмо