purebasic.info

PureBasic forum
Текущее время: Ср дек 12, 2018 4:16 am

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 48 ]  На страницу 1, 2, 3, 4  След.
Автор Сообщение
 Заголовок сообщения: PureBasic и AsmInline
СообщениеДобавлено: Пн фев 16, 2009 4:32 pm 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
В Help'е PureBasic очень слабо освещен вопрос по ассемблерным вставкам(далее "АВ"). Поэтому создаю этот топик, что бы восполнить это упущение:)
По моему глубокому убеждению "АВ" могут существенно повысить скорость выполнения программы и сократить скомпилированный код. Ниже я постараюсь это подтвердить.
Для начала, чтобы акивировать AsmInline необходимо в опциях компилятора установить галку Enable inline ASM support.
1.Чтобы использовать переменные нужно их объявлять до использования в "АВ", т.е. такой код скомпилируется
Код:
1
2
3
 
asd.l
MOV asd, EAX


а такой нет
Код:
1
2
 
MOV asd.l, EAX



2. Для того, чтобы записать в переменную значение регистра, или другой переменной, необходимо ипользовать перед именем переменной префикс v_
Поясню на примере:
Код:
1
2
3
4
5
 
string1.s="WORLD"
string2.s
MOV eax, string1        ; записываем в EAX адрес строки string1
MOV [v_string2], EAX    ; записываем в переменную string2 значение регистра EAX, теперь string2="WORLD"


Многие возразят, что этот код аналогичен следующему:
Код:
1
2
3
 
string1.s="WORLD"
string2.s=string1


Соглащусь с этим, но, скомпилите два экзешника и сравните размер. У меня получилось 3584 байта в первом случае и 4096 во втором

3. Метки в "АВ" дожны выглядеть так: восклицательный знак<Имя метки>двоеточие
Пример
Код:
1
2
3
4
5
 
    MOV ecx, 100
! metka:
    DEC ecx
    JNE metka


Примечание: Имя метки не должно начинаться с цифры

4. Желательно при использовании "АВ" сохранять и восстанавливать регистры
Код:
1
2
3
4
5
6
7
 
    PUSH ECX               ; сохраняем регистр ECX в стеке
    MOV ecx, 100
! metka:
    DEC ecx
    JNE metka
    POP ECX                ; восстанавливаем ECX


Примечание: Если вы выносите"АВ" в отдельную процедуру, то сохранением и восстановлением регистров нужно пользоваться с осторожностью, т.к. аргументы в процедуру передаются через стек, а сохраняя регистры мы тем самым сдвигаем указатель стека.

5. Ну и на последок приведу пример по скорости выполнения кода (очень впечатляет)
Мне как то потребовалось в утилите заполнять ооочень большие массивы...
Два кода. В обох из длинной строки, символы (в данном случае пробелы) записываются в массив
№1
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
string.s=Space(469440)
temp.b
Dim mass.b(78239 ,5)
time=GetTickCount_()
For i=0 To 78239
 For j=0 To 5
  MOV eax, string         ; в EAX адрес string
  MOV al, byte[eax]       ; в AL ASCII код символа
  MOV temp, al
  mass(i, j)=temp         ; записываем очередной символ в массив
  INC string              ; сдвигаем переменную string на один символ влево
 Next j
Next i
time=GetTickCount_()-time
MessageRequester("o_O", "Время с ASM вставкой:  "+ Str(time), #MB_OK|#MB_ICONINFORMATION)


№2
Код:
1
2
3
4
5
6
7
8
9
10
11
12
 
string.s=Space(469440)
Dim mass.b(78239 ,5)
time=GetTickCount_()
For i=0 To 78239
 For j=0 To 5
   mass(i, j) = Asc(Mid(string, 1, 1))    ; записываем очередной символ в массив
   string=Right(string, Len(string)-1)    ; сдвигаем переменную string на один символ влево
 Next j
Next i
time=GetTickCount_()-time
MessageRequester("o_O", "Время PureBasic Code:  "+ Str(time), #MB_OK|#MB_ICONINFORMATION)


Теперь скомпилим и посмотрим размеры экзешников: №1 - 6144 байта, №2 - 7168 байт
Запустим первый (очень быстро выполнится), потом второй(а тут запаситесь терпением:)
P.S. Я не призываю использовать ассемблерные вставки где не попадя. Но использование "АВ" в длинных циклах, в процедурах, которые вызываются много раз, иногда может принести ощутимый выигрышь в скорости.
P.P.S. Для отладки своих приложений очень сильно может помоч низкоуровневый отладчик OllyDbg скачть можно отсюда http://www.ollydbg.de/odbg110.zip
Иногда бывает приложение компилится нормально, но во время выполнения выскакивает аксес виолант по доступу к памяти. Вот в таких случаях OllyDbg просто незаменим. Да и просто посмотреть на свой скомпиленный код интересно, а иногда и полезно. Можно глянуть и сравнить те примеры, что я привел выше.
P.P.P.S. Большая просьба, обсуждать в этой теме, только вопросы связанные с ASMINLINE. Похожая тема уже была, но она уехала в сторону. Поэтому создал новую.


Последний раз редактировалось pablov Вт фев 17, 2009 12:27 pm, всего редактировалось 2 раз(а).

Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн фев 16, 2009 5:02 pm 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6411
Благодарил (а): 21 раз.
Поблагодарили: 200 раз.
Пункты репутации: 52
Да, тема несомненно нужная. Особенно интересны практические выкладки.

_________________
read-only ¯\_(ツ)_/¯


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн фев 16, 2009 11:25 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Пн ноя 27, 2006 2:43 pm
Сообщений: 933
Откуда: Санкт-Петербург
Благодарил (а): 1 раз.
Поблагодарили: 12 раз.
Пункты репутации: 15
потом перенесу в
трюки и советы по программированию на Purebasic

8)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 17, 2009 9:13 am 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11336
Благодарил (а): 4 раз.
Поблагодарили: 443 раз.
pablov писал(а):
Для отладки своих приложений очень сильно может помоч низкоуровневый отладчик OllyDbg скачть можно отсюда

А есть что-то подобное но полностью на великом и могучем?

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 17, 2009 12:18 pm 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
Пётр
Тут найдешь на великом и могучем :D и русский хелп к OllyDbg


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 17, 2009 12:55 pm 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6411
Благодарил (а): 21 раз.
Поблагодарили: 200 раз.
Пункты репутации: 52
Пётр писал(а):
А есть что-то подобное но полностью на великом и могучем?


А самая лучшее описание полностью на русском и с картинками есть на http://wasm.ru

Исключительно полезно, особенно тем, кто вообще ни чего не знает ни о Ольке ни о реверсинге программ.

Цикл: Введение в крэкинг с нуля, используя OllyDbg.

У меня есть все 39 глав. В ZIP около 22 метров. Если кому лень всё самому качать, то могу выложить куда нибудь...

_________________
read-only ¯\_(ツ)_/¯


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 17, 2009 2:18 pm 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
kvitaliy писал(а):
Исключительно полезно, особенно тем, кто вообще ни чего не знает ни о Ольке ни о реверсинге программ.

+1

_________________
Всё должно быть просто, настолько просто, насколько возможно, но не проще. (c) Альберт Эйнштейн
Изображение


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 17, 2009 4:16 pm 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
kvitaliy писал(а):
Особенно интересны практические выкладки.

Здесь я предлагаю вашему вниманию три процедуры: 1. проверка строки на число или не число(имеется ввиду десятичное) 2. конвертация HEX строки в десятичное число 3. преобразование строки в HEX формат
Кстати, по поводу конвертации HEX строки в десятичное число. В библиотеке Droopy Library есть функция Hex2Dec(HexNumber.s). Но она работает не совсем корректно. Поясню. Шестнадцатеричный формат подразумевает использование цифровых символов 1...9 и буквенных A B C D E F Теперь попробуйте выполнить следующий код
ResultTemp.l=Hex2Dec("1ARD") Эта ф-ия вернет 7101, хотя символ "R" не соответствует HEX формату. Функция должна либо ругнуться, либо вернуть ноль.
Вот собственно выкладки
Код:
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
 
Enumeration
  #Window_0
EndEnumeration
Enumeration
  #String_0
  #Button_1
  #Button_2
  #Button_3
EndEnumeration
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
Procedure.b CheckNumber(str$)
; Процедура проверяет строку на наличие цифр и возвращает -1 в случае пустой строки,
; 1 в случае если все символы - цифры и 0 если есть не цифровые символы
    MOV eax, str$
    MOV bl, byte[eax]
    CMP bl, 0              ; проверяем пустая строка или нет
    JNE _loop1
  ProcedureReturn -1
!_loop1:
    MOV bl, byte[eax]
    CMP bl, 0              ; проверяем конец строки
    JE endproc1
    CMP bl, $39             ; если BL меньше или равно девяти
    JBE _11                 ; тогда проверяем дальше
  ProcedureReturn 0
!_11:
   CMP bl, $30             ; если BL больше или равно нулю
    JAE _22                 ; тогда проверяем дальше
  ProcedureReturn 0
!_22:
    INC eax                 ; сдвигаем строку влево
    JMP _loop1
!endproc1:  
  ProcedureReturn 1
EndProcedure
 
Procedure.l HexStrToNumber(str$)
  ; Процедура конвертирует HEX строку в десятичное число. В случае успеха, возвращает десятичное
  ; число. В сучае пустой строки, или если число не имеет HEX фрмата (встречаются символы отличные от 0..1;
  ; A..F; a..f) процедура возвращает ноль.
 ;LOCALS
  ResultTemp.l
     MOV eax, str$
     XOR ecx, ecx
     XOR ebx, ebx
     MOV bl, byte[eax]
     CMP bl, 0              ; проверяем пустая строка или нет
     JE endproc
!_loop:
    CMP bl, $30            ; 0...9
     JB  _1
     CMP bl, $39
     JA  _1
     SUB bl, $30
     JMP _2
  ! _1:  
     CMP bl, $41             ; A...F
     JB  _4
     CMP bl, $46
     JA  _4
     SUB bl, $37
     JMP _2
  ! _4:  
     CMP bl, $61             ; a...f
     JB  _3
     CMP bl, $66
     JA  _3
     SUB bl, $57
     JMP _2
  ! _3:
   ProcedureReturn 0
  ! _2:  
     OR  ecx, ebx
     INC eax
     MOV bl, byte[eax]
     CMP bl, 0              ; проверяем конец строки
     JE endproc
     SHL ecx, 4
     JMP _loop
  !endproc:
     MOV ResultTemp, ecx
  ProcedureReturn ResultTemp
EndProcedure
 
Procedure.s StrToHexVal(str$)
 ; Процедура преобразует строку в HEX представление
 ;LOCALS
  ResultTemp.s=Space(1024)
     MOV esi, str$
     CMP byte [esi], 0       ; проверяем пустая строка или нет
     JE endproc2
     MOV edi, ResultTemp                                    
     XOR eax, eax
!_rr:        
     MOV al, byte [esi]      ; берем символ из строки
     MOV bl, al
     SHR eax, 4
     ADD al, $90
     DAA
     ADC al, $40
     DAA
     MOV byte [edi], al      ; пишем текстовую строку
     INC edi
     MOV al, bl
     AND eax, $0F
     ADD al, $90
     DAA
     ADC al, $40
     DAA
     MOV byte [edi], al      ; пишем текстовую строку
     INC esi
     INC edi
     CMP byte [esi], 0       ; если строка не кончилась, пилим дальше
     JNZ _rr
     MOV byte [edi], 0       ; записываем в конец строки ноль
 ProcedureReturn ResultTemp    
!endproc2:
 ProcedureReturn ""
EndProcedure
 
Procedure OpenWindow_Window_0()
  If OpenWindow(#Window_0, 450, 200, 474, 160, "AsmInline", #PB_Window_MinimizeGadget)
    StringGadget(#String_0, 10, 10, 445, 25, "")
    ButtonGadget(#Button_1, 310, 60, 145, 25, "CheckNumber")
    ButtonGadget(#Button_2, 310, 85, 145, 25, "HexStrToNumber")
    ButtonGadget(#Button_3, 310, 110, 145, 25, "StrToHexVal")
  EndIf
EndProcedure
Procedure Button_1_OnEvent(EventType.l)
  a= CheckNumber(GetGadgetText(#String_0))
  MessageRequester("o_O", "Return:  "+ Str(a), #MB_OK|#MB_ICONINFORMATION)
EndProcedure
Procedure Button_2_OnEvent(EventType.l)
  a= HexStrToNumber(GetGadgetText(#String_0))
  b=Hex2Dec(GetGadgetText(#String_0)) ; Используем Droopy Library Оставлено для сравнения. Введите строку 1ARD и посмотрите что получится
  MessageRequester("o_O", "Return:  " + Str(a) + "  " + Str(b), #MB_OK|#MB_ICONINFORMATION)
EndProcedure
Procedure Button_3_OnEvent(EventType.l)
  a.s= StrToHexVal(GetGadgetText(#String_0))
  MessageRequester("o_O", "Return:  " +a, #MB_OK|#MB_ICONINFORMATION)
EndProcedure
OpenWindow_Window_0()
Repeat
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_Gadget
      EventGadget = EventGadget()
      EventType = EventType()
      If EventGadget = #String_0
      ElseIf EventGadget = #Button_1
        Button_1_OnEvent(EventType)              ; CheckNumber
      ElseIf EventGadget = #Button_2
        Button_2_OnEvent(EventType)              ; HexStrToNumber
      ElseIf EventGadget = #Button_3
        Button_3_OnEvent(EventType)              ; StrToHexVal
      EndIf
    Case #PB_Event_CloseWindow
      EventWindow = EventWindow()
      If EventWindow = #Window_0
        CloseWindow(#Window_0)
        Break
      EndIf
  EndSelect
ForEver


Прошу обратить внимание, если одна и таже ассемблерная вставка используется не много раз (три и менее), тогда не стоит ее оформлять в отдельную процедуру. Дело в том, что PureBasic во время компиляции при создании процедуры создает дополнительный код, который может свести на нет все ассемблерные ухищрения.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Вт фев 17, 2009 7:16 pm 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6411
Благодарил (а): 21 раз.
Поблагодарили: 200 раз.
Пункты репутации: 52
Max число FFFFFFF. А можно как то увеличить?

_________________
read-only ¯\_(ツ)_/¯


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср фев 18, 2009 8:40 am 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
kvitaliy писал(а):
Max число FFFFFFF

ну почему, попробуй 7FFFFFFF
А вообще странно, к примеру число FFFFFFF1 win калькулятор переводит в 4294967281, OllyDbg в 2147483647 а мой алгоритм и HEX2DEC из друпии преобразует в -15 :shock:


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср фев 18, 2009 9:58 am 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11336
Благодарил (а): 4 раз.
Поблагодарили: 443 раз.
pablov писал(а):
а мой алгоритм и HEX2DEC из друпии преобразует в -15
Попробуй заметить 4-ёх байтные переменные на 8-ми байтные. :)

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср фев 18, 2009 10:37 am 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
Пётр писал(а):
Попробуй заметить 4-ёх байтные переменные на 8-ми байтные.

Где?
Попрбовал ResultTemp.d и ResultTemp.q - не компилит

_________________
Всё должно быть просто, настолько просто, насколько возможно, но не проще. (c) Альберт Эйнштейн
Изображение


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср фев 18, 2009 10:51 am 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11336
Благодарил (а): 4 раз.
Поблагодарили: 443 раз.
Я в асме не очень разбираюсь, поэтому что-то конкретное посоветовать не могу.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср фев 18, 2009 11:07 am 
Не в сети
профессор

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
Петро, судя по топикам, ты занимаешься микроконтролерами, работаешь с COM портом и т.д. Тогда срочно! изучать ассемблер, читать Калашникова, и это http://cracklab.ru/rar/dl/CRACKLAB.rU_8.rar (там есть продолжение) И не так страшен этот черт, в смысле ассемблер, как его малюют :D

_________________
Всё должно быть просто, настолько просто, насколько возможно, но не проще. (c) Альберт Эйнштейн
Изображение


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Ср фев 18, 2009 11:58 am 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11336
Благодарил (а): 4 раз.
Поблагодарили: 443 раз.
По читаю...

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 48 ]  На страницу 1, 2, 3, 4  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB