Форум программистов, компьютерный форум, киберфорум
Delphi
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
419 / 416 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
1

Вставка на асме

06.10.2010, 01:31. Просмотров 1353. Ответов 18
Метки нет (Все метки)

подскажите пожалуйста, как вот это правильно написать на асме:
Код
      mov ah,data^[i]
      mov al,data[i+1]
      mov data^[i],al
      mov data^[i+1],ah
у меня вот так получилось, но оно ничего не делает
Assembler
1
2
3
4
      mov ah,byte ptr[data+i]
      mov al,byte ptr[data+i+1]
      mov byte ptr[data+i],al
      mov byte ptr[data+i+1],ah
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.10.2010, 01:31
Ответы с готовыми решениями:

Морфинг на Асме
Нужно реализировать прогу для морфинга изображение, при которой одно изображение плавно переходит в...

ошибка в асме
не могу найти ошибку :(( вычисляет не правильно в коде асма... #include "stdafx.h" #include...

Логические операции на асме.
Дан массив из 5 байт. Рассматривая его как массив из 8 пятиразрядных слов, найти “исключающее или”...

Переписать на асме код Си. e^x
помогите с программой. Нужно зделать вставку на ассемблере в СИ код. Вставка должна выполнять...

18
КотЪ
219 / 219 / 60
Регистрация: 26.05.2009
Сообщений: 688
06.10.2010, 11:00 2
А если использовать ключевое слово asm?
Delphi
1
2
3
4
5
6
asm
  mov ah,data^[i]
  mov al,data[i+1]
  mov data^[i],al
  mov data^[i+1],ah
end;
Кроме того, после описания функций на асме разрабы Делфи иногда пишут ключевое слово assembler, вот зачем - не знаю пока
Например:
Delphi
1
function StrComp(const Str1, Str2: PChar): Integer; assembler;
0
211 / 193 / 42
Регистрация: 17.04.2010
Сообщений: 445
06.10.2010, 13:30 3
Vas-e-na, тебе нужно поменять два байта в массиве местами?
Delphi
1
2
3
4
5
6
procedure swap(a: pointer); assembler;
asm
  rol   word ptr [eax], 8
end;
...
swap(@data[i]);
или вставкой
Delphi
1
2
3
4
asm
  lea  edx, data[i]
  rol  word ptr [edx], 8
end;
0
Retired
7719 / 2551 / 671
Регистрация: 17.10.2009
Сообщений: 5,100
06.10.2010, 14:24 4
Цитата Сообщение от Zabiyak Посмотреть сообщение
Кроме того, после описания функций на асме разрабы Делфи иногда пишут ключевое слово assembler, вот зачем - не знаю пока
Если мы используем директиву assembler, то такая подпрограмма становится ассемблерной. Эти подпрограммы не содержат begin ... end и состоят только из оператора asm ... end.
0
419 / 416 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
06.10.2010, 16:38  [ТС] 5
Цитата Сообщение от Zabiyak Посмотреть сообщение
А если использовать ключевое слово asm?
я похож на полного дятла???

Добавлено через 36 секунд
x128, если бы был просто массив, а у меня указатель на массив, в этом вся соль!!!
0
211 / 193 / 42
Регистрация: 17.04.2010
Сообщений: 445
06.10.2010, 17:00 6
Vas-e-na, в варианте с процедурой указатель и передается, можно добавить еще смещение и получится что-то такое:
Delphi
1
2
3
4
5
6
procedure swap(a: pointer; p: integer); assembler;
asm
  rol   word ptr [eax][edx], 8
end;
...
swap(data, i);
или

Delphi
1
2
3
4
5
asm
  mov   edx, data
  mov   ecx, i
  rol   word ptr [edx+ecx], 8
end;
1
КотЪ
219 / 219 / 60
Регистрация: 26.05.2009
Сообщений: 688
07.10.2010, 11:05 7
Цитата Сообщение от Vas-e-na Посмотреть сообщение
я похож на полного дятла???
Ага, судя по аватаре, на дятла вы явно не похожи...
Вообще, поскольку в вашем коде в стартовом топике этого тега не было, то вполне логично предположить, что вы его не ставили. А грубить не нужно, я к вам вполне спокойно и вежливо обращался.
0
419 / 416 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
07.10.2010, 20:35  [ТС] 8
x128, написал как вы сказали:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
procedure TTextFrameData.ConvertBOM;
var i,j:longword;
begin
  i:=1;
  while i<Length(DataArray^)-2 do
  begin
    asm
      mov edx, DataArray
      add ecx, i
      rol word ptr [edx+ecx], 8
    end;
    Inc(i,2);
  end;
end;
но теперь мало того что не работает, так еще и ошибка вылетает, ибо вместо реального адреса ($AF0ED0) в edx записывается 12 ($0D), что я делаю не так???
PS
Delphi
1
2
3
4
5
type
  ByteArray: array of byte;
  pByteArray: ^ByteArray;
[...]
  var DataArray: pByteArray
0
4007 / 1730 / 200
Регистрация: 06.10.2010
Сообщений: 3,871
07.10.2010, 20:57 9
Чувак, используй swap - оно делает то, что нужно и никакого асма.

Но если надо обязательно на асме тогда так
Delphi
1
2
3
4
5
6
7
8
9
10
a:=length(DataArray);
asm
mov  eax,[a]
lea  edx,[eax+eax]
neg  eax
add  edx,[DataArray]
@@:rol word[edx+eax*2],8
   inc eax
jne @@
end;
0
419 / 416 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
07.10.2010, 21:17  [ТС] 10
murderer, чувак, твой код, и первая же строка с ошибкой, это так для справки, и как же ты предлагаешь swap использовать???
0
211 / 193 / 42
Регистрация: 17.04.2010
Сообщений: 445
07.10.2010, 21:42 11
но теперь мало того что не работает, так еще и ошибка вылетает, ибо вместо реального адреса ($AF0ED0) в edx записывается 12 ($0D), что я делаю не так???
Я что-то не уловил твоей игры с указателями и объявлением массива... DataArray у тебя глобально объявлен? Покажи код где ты инициализируешь массив и как попадает указатель в DataArray.
и как же ты предлагаешь swap использовать???
Можно и swap, разницы нет. Использование асма обязательное условие или это относится к оптимизации, или просто так пытаешься решить проблему?
Опиши подробней задачу, какие ограничения или обязательные условия, а то если честно, я не совсем уловил логику.
0
4007 / 1730 / 200
Регистрация: 06.10.2010
Сообщений: 3,871
07.10.2010, 21:42 12
твой код, и первая же строка с ошибкой
Там галочка не обязательна на Delphi 7 и так работает (если DataArray - это динамический массив).

как же ты предлагаешь swap использовать???
swap меняет старший и младший байты в word`е местами. Тебе ведь это нужно?
0
419 / 416 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
07.10.2010, 22:37  [ТС] 13
Итак по порядку:
Цель не вставка на асме, а ускорения процедуры (т.е. грубо говоря оптимизация), поэтому асм и выбран, если есть другое решение но сравнимое по "скорости" работы готов принять.
Что имеется:
типы:
Delphi
1
2
3
type
  ByteArray = array of byte;
  pByteArray = ^ByteArray;
класс1:
Delphi
1
2
3
4
5
TFrameData = class
  private
    Size: longword;
    Flags: word;
    Data: pByteArray;
класс2:
Delphi
1
2
3
4
TTextFrameData = class(TFrameData)
  private
    Encoding: byte;
    procedure ConvertBOM;  // вот собственно та процедура
процедура: (щас без асма чтоб была понятна соль)
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
procedure TTextFrameData.ConvertBOM;
var i:longword;
    tmp: byte;
begin
  i:=1;
  while i<Length(Data^)-1 do
  begin
    tmp:=Data^[i];
    Data^[i]:=Data^[i+1];
    Data^[i+1]:=tmp;
    Inc(i,2);
  end;
end;
вот в принципе и всё...
Цитата Сообщение от murderer Посмотреть сообщение
swap меняет старший и младший байты в word`е местами. Тебе ведь это нужно?
у меня байты, а не ворды
Цитата Сообщение от murderer Посмотреть сообщение
Там галочка не обязательна на Delphi 7 и так работает (если DataArray - это динамический массив).
у меня не просто динамический массив, а ссылка на него!!! (потом такие мелочи - культура программирования ИМХО)
0
211 / 193 / 42
Регистрация: 17.04.2010
Сообщений: 445
08.10.2010, 00:03 14
Vas-e-na, держи два варианта:
1) с использованием swap, этот вариант в 3 раза быстрей твоего
Delphi
1
2
3
4
5
6
7
8
9
10
11
procedure ConvertBOM;
var
  i,j: longword;
begin
  i:=1; j:=Length(Data^)-2;
  while i<j do
  begin
    pWord(dword(Data^)+i)^:=Swap(pWord(dword(Data^)+i)^);
    Inc(i,2);
  end;
end;
2) асм, примерно на 20-25% быстрей первого варианта
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
procedure ConvertBOM;
var
  i,j: longword;
  t: pointer;
begin
  i:=1; j:=Length(Data^)-2;
  t:=@Data^[i];
  asm
    mov   edx, t
    mov   ecx, j
    add   ecx, edx
    @@loop:
    rol   word ptr [edx], 8
    add   edx, 2
    cmp   edx, ecx
    jb    @@loop
  end;
end;
скорость замерял на массиве размерностью 65536 элементов и учитывал среднее время при 10000 вызовов процедуры
1
4007 / 1730 / 200
Регистрация: 06.10.2010
Сообщений: 3,871
08.10.2010, 09:10 15
Так должно быть ещё немного быстрей.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure ConvertBOM;
var
  j: longword;
begin
  j:=Length(Data^)-2;
  asm
    mov   edx,[Data]
    mov   edx,[edx]
    mov   ecx,[j]
    lea   edx,[edx+ecx+1]
    shr   ecx,1
    neg   ecx
    @@:rol word[edx+ecx*2],8
       inc ecx
    jne @@
  end;
end;
Ещё можно использовать SSSE3 (проверить не могу, возможны глюки).

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
procedure ConvertBOMSSSE3;
const
  a: array[0..15] of byte=(1,0,3,2,5,4,7,6,9,8,11,10,13,12,15,14);
var
  j: longword;
begin
  j:=Length(Data^)-2;
  asm
    mov    edx,[Data]
    mov    edx,[edx]
    mov    ecx,[j]
    lea    edx,[edx+ecx+1]
    mov    eax,ecx
    //Вначале обрабатываем словами по 16 байт
    and    ecx,-16
    neg    ecx
    movups xmm1,[a]
    @1:movups xmm0,[edx+ecx]
       db 66h,0Fh,38h,00h,0C1h //pshufb xmm0,xmm1
       movups [edx+ecx],xmm0
       add    ecx,16
    jne @1
    //Затем обрабатываем остаток
    cmp eax,1
    jna @quit
        shr eax,1
        neg eax
        @2:rol word[edx+eax*2],8
           inc eax
        jne @2
    @quit:
  end;
end;
Для правильной работы выражение "Length(Data^)-2" должно быть больше или равно 16.
1
419 / 416 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
08.10.2010, 13:45  [ТС] 16
x128, в общем заработал вариант №2 (первый даже не брал но думаю работает...)
murderer, опять же не работает, та же проблема, не хочен он делать:
Assembler
1
mov edx,[Data]
а второй вариант уж слишком мудреный, на столько мне ускорять прогу не надо (да и длинна может быть меньше 16-ти...)...
0
4007 / 1730 / 200
Регистрация: 06.10.2010
Сообщений: 3,871
08.10.2010, 14:14 17
Vas-e-na
там не просто mov edx,[Data]
Assembler
1
2
3
4
5
mov    edx,[Data] ;Получаем указатель на указатель на массив, то есть Data
mov    edx,[edx]  ;получаем указатель на массив, то есть Data^
mov    ecx,[j]     
lea    edx,[edx+ecx+1] ;получаем указатель на предпоследний элемент массива, то есть @Data^[length(Data^)-2]
;дальше обработка идёт с конца. Это позволяет сэкономить одну инструкцию в цикле.
У меня работает.

Но не заморачивайся выигрыш ничтожный.
0
419 / 416 / 79
Регистрация: 21.06.2010
Сообщений: 1,362
08.10.2010, 15:47  [ТС] 18
murderer, суть не в том просто или не просто, ошибка которую я описывал выше там происходит... (Вставка на асме)
0
4007 / 1730 / 200
Регистрация: 06.10.2010
Сообщений: 3,871
08.10.2010, 16:56 19
Vas-e-na
Нашёл глюк в своём коде: если размер массива чётный, то обработка начнётся с элемента с индексом 2. Но это не приводит к ошибке. Во вложении исправленый код который я тестировал.
0
Вложения
Тип файла: rar Project2.rar (365 байт, 15 просмотров)
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.10.2010, 16:56

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Проект на асме в Eclipse
Коллеги, подкажите, как можно в Eclipse писать прошивку под AVR на голом асме? Отдельные функции я...

Рекурсивный фильтр на асме
Добрый день! Подскажите пожалуйста, как наиболее эффективно реализовать на интеловском ассемблере...

Пространство имён на асме
Подскажите новичку. Интересно, можно ли организовать ограничение области видимости для меток в...

std::map в инлайн-асме
Доброго времени суток Имеется MAP-массив содержащий хуки для функций Нужно получить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.