purebasic.info

PureBasic forum
Текущее время: Сб дек 15, 2018 7:23 pm

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




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

Зарегистрирован: Вс май 04, 2008 12:18 am
Сообщений: 434
Откуда: PointOfPresence.Ru
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
давно пора про асм топик сделать было четкий

будет время - сам отпишу чего полезного

_________________
Изображение Точка.Присутствия - каждому по потребностям!


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

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
Продолжу тему.
Вот пример практической реализации AsmInline
Код:
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
 
; Утилита для конвертации файла в формат PureBasic (для DataSection)
;DataSection
;Data.b  $6A,$0D,$0A,$4E,$65,$78,$74,$20,$69,$0D,$0A,$0D,$0A,$CF,$E5,$F0
;Data.b  $E2,$FB,$E9,$20,$E2,$E0,$F0,$E8,$E0,$ED,$F2,$20,$ED,$E0,$20,$35
;......................
;Data.b  $31,$32,$20,$E1,$E0,$E9,$F2,$20,$EC,$E5,$ED,$FC,$F8,$E5,$20,$E2
;Data.b  $F2,$EE,$F0,$EE,$E3,$EE
;EndDataSection
;###############################################################################
; В свойствах компилятора необходимо установить галку Enable inline ASM support
;###############################################################################
Global ResT.s=Space(4)
Procedure.s Hex2Str(HB)
   ;Процедура конвертирует байт (HEX-число) в строку, добавляет символ '$' и запятую пр. "$5F,"
   MOV eax, ResT
   MOV edx, HB
   MOV byte [eax], "$"
   INC eax
   MOV dh,dl                
   MOV cl,4
   SHR dl,cl
   CMP dl,0Ah      
   JAE HEX_LETTER
   ADD dl,30h
   JMP WRITE_DIGIT
! HEX_LETTER:
  ADD  dl,37h
! WRITE_DIGIT:
  MOV [eax], dl
   INC eax
   MOV dl,dh
   AND dl,0Fh
   CMP dl,0Ah      
   JAE HEX_LETTER1
   ADD dl,30h
   JMP WRITE_DIGIT1
! HEX_LETTER1:
  ADD dl,37h
! WRITE_DIGIT1:
  MOV [eax], dl
   INC eax
   MOV byte [eax], ","
   INC eax
   MOV byte[eax], 0
ProcedureReturn ResT
EndProcedure
 
Procedure.s Del(ST.s)
   MOV eax, ST
   CMP byte [eax], 0
   JZ nosrt
! lop1:
   INC eax                  ; Сдвигаем указатель на строку вправо
   CMP byte [eax], 0        ; Т.к. строка должна завершаться нулем, ищем ноль (т.е. конец строки)
   JNZ nozero                
   DEC eax                  ; и когда находим, смещаем указатель на один байт влево
   MOV byte [eax], 0        ; и записываем вместо запятой ноль.
   JMP nosrt
! nozero:
   JMP lop1
! nosrt:
ProcedureReturn ST
EndProcedure  
;LOCALS
 byte.b
 string.s
 n.b
 file$=OpenFileRequester("Choose a file", "", "*.*", 0)
If file$
 hFileCr=CreateFile_(file$,#GENERIC_READ,#FILE_SHARE_READ|#FILE_SHARE_WRITE,NULL,#OPEN_EXISTING,GetFileAttributes_(file$),NULL)      
       
   If hFileCr = -1 Or hFileCr = 0
             MessageRequester("Attention", "Can Not open file" + Chr(10) + "Possible file is occupied other program.", #MB_OK|#MB_ICONWARNING)
      Else
          CreateFile(0, GetCurrentDirectory()+"DataSec.txt")
          length = GetFileSize_(hFileCr, pFileSizeHigh.l)
          hFileMap = CreateFileMapping_(hFileCr, 0, 8, 0, 0, 0)      
          MapVOF = MapViewOfFile_(hFileMap, 1, 0, 0, length)  ; Создаем проекцию файла в памяти и получаем на нее указатель
          CloseHandle_(hFileCr)    
           MOV n, 16                                     ; Будем писать в одном ряду по 16 байт. Можно изменить на другое значение
     ! lop:
           XOR ebx, ebx
           MOV eax, MapVOF
           MOV bl, [eax]
           INC eax
           MOV MapVOF, eax
           MOV byte, bl
           string=string+Hex2Str(byte)                   ; Конвертируем байт в строку и добавляем символ $ и запятую        
           DEC length                                
           CMP length, 0                                 ; Проверяем конец файла
           JZ endfile
           DEC n
           CMP n, 0
           JNZ NoW
           string=Del(string)                            ; Убираем запятую в конце строки
           WriteStringN(0, "Data.b  "+ string)
           string=""
           MOV n, 16
     ! NoW:
          JMP lop
           DEC length
           JNZ lop
     ! endfile:
         string=Del(string)                             ; Убираем запятую в конце строки
          WriteStringN(0, "Data.b  "+ string)
     UnmapViewOfFile_(MapVOF)
     MessageRequester("Saved", "Data are successfully saved in file 'DataSec.txt'", #MB_OK|#MB_ICONINFORMATION)
   EndIf
EndIf
  End
 



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PureBasic и AsmInline
СообщениеДобавлено: Вс дек 20, 2009 11:06 pm 
Не в сети
студент

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


а такой нет
Код:
1
2
3
 
 
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. Похожая тема уже была, но она уехала в сторону. Поэтому создал новую.

Код:
1
string=Right(string, Len(string)-1


К чему тут эта гнилая конструкция?
---
Вот, визуализировал (само собой, что скорость вычислений будет чуток ниже):
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ii = Val(InputRequester("", "Lenght of elements in first dimenssion: ", "28200")) : jj = 5 : all = ii * jj : temp.b : time = Date() : string.s=Space(all) : Dim mass.b(ii - 1 ,jj - 1)
Procedure main_proc()
 Shared ii, jj, all, temp, time, string, mass(), mutex
 For i=0 To ii - 1 : For j=0 To jj - 1 : mass(i, j) = Asc(Mid(string, j * i + 1, 1)) : Next j
  If i - k > 199 Or i = ii - 1 : k = i : summary = i * jj : percents.d = (summary / all) * 100 : SetGadgetState(10, Int(percents * 1000)) : SetGadgetText(0, Str(summary) + "/" + Str(all) + " (" + StrD(percents, 2) + "% : " + StrD(summary / 1024, 2) + "KiB) : " + Str(Date() - time) + " seconds elapsed without inline ASM...") : EndIf
  event = WindowEvent() : gadget = EventGadget() : If gadget = 3 : End : EndIf
 Next i
 HideGadget(10, 1) : HideGadget(20, 0) : SetGadgetText(1, "Seconds elsepsed without inline ASM:  " + Str(Date() - time)) : time = Date() : k = 0
  For i=0 To ii - 1 : For j=0 To jj - 1 : MOV eax, string : MOV al, byte[eax] : MOV temp, al : INC string : mass(i, j) = temp : Next j
   If i - k > 199 Or i = ii - 1 : k = i : summary = i * jj : percents.d = (summary / all) * 100 : SetGadgetState(20, Int(percents * 1000)) : SetGadgetText(0, Str(summary) + "/" + Str(all) + " (" + StrD(percents, 2) + "% : " + StrD(summary / 1024, 2) + "KiB) : " + Str(Date() - time) + " seconds elapsed with inline ASM...") : EndIf
   event = WindowEvent() : gadget = EventGadget() : If gadget = 3 : End : EndIf
  Next i
 HideGadget(20, 1) : HideGadget(2, 0) : SetGadgetText(2, "Seconds elapsed with inline ASM:  " + Str(Date() - time)) : DisableGadget(3, 0)
EndProcedure
If OpenWindow(#PB_Any, 0, 0, 600, 130, "productivity test", #PB_Window_BorderLess | #PB_Window_ScreenCentered)
TextGadget(0, 5,  5, 590, 40, "Waiting for first thousand of elements...", #PB_Text_Center)
TextGadget(1, 5, 50, 590, 25, "", #PB_Text_Center) : ProgressBarGadget(10, 5, 50, 590, 25, 0, 100000)
TextGadget(2, 5, 80, 590, 25, "", #PB_Text_Center) : ProgressBarGadget(20, 5, 80, 590, 25, 0, 100000) : HideGadget(20, 1) : HideGadget(2, 1)
ButtonGadget(3, 5, 110, 590, 15, "", #PB_Button_Default)
main_proc()
Repeat : event = WindowEvent() : gadget = EventGadget() : If gadget = 3 : Break : EndIf : Delay(1) : ForEver : EndIf


Цитата:
4.30 на Линухе

Цитата:
а тут запаситесь терпением

Это вам, уважаемый, нужно запастись внимательностью. ;)


Последний раз редактировалось ResX Чт дек 24, 2009 8:38 pm, всего редактировалось 1 раз.

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

Зарегистрирован: Вс окт 25, 2009 5:48 pm
Сообщений: 263
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Цитата:
Вот, визуализировал (само собой, что скорость вычислений будет чуток ниже):

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


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Чт дек 24, 2009 8:22 pm 
Не в сети
студент

Зарегистрирован: Вс дек 20, 2009 10:12 pm
Сообщений: 8
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
haav писал(а):
Цитата:
Вот, визуализировал (само собой, что скорость вычислений будет чуток ниже):

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

чтоб не сидеть, гадать, а когда же оно посчитает. а видеть поисходящее в реальном времени.
это относится к объему массива - чем дальше, тем медленнее. и это можно регистрировать, в итоге, зрением, а не только абстрактным мышлением. (так проще понять суть вещей. ведь как не крути, а мы, всё же - люди)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: PureBasic и AsmInline
СообщениеДобавлено: Чт дек 24, 2009 8:37 pm 
Не в сети
студент

Зарегистрирован: Вс дек 20, 2009 10:12 pm
Сообщений: 8
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
Код:
1
2
3
 
INC string              ; сдвигаем переменную string на один символ влево
 


Код:
1
2
3
 
string=Right(string, Len(string)-1)     ; сдвигаем переменную string на один символ влево
 



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


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

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
Уважаемый ResX, я что-то не понял, в чем смысл ваших постов. Вы против ассемблерных вставок? Или вы за визуализацию? Или, "Чтобы всем" © Шариков.
Я постил для того, чтобы показать, как при помощи асм. вставок можно существенно сократить время выполнения и размер выходного кода
ResX писал(а):
Вот, визуализировал (само собой, что скорость вычислений будет чуток ниже):

Из вашего кода (кста, в каком заведении вас учили так оформлять код. Все очень наглядно) при ii =128200 время выполнения в первом случае составляет ~140 секунд, во втором 1 сек. Нихрена себе чуток :D И это с учетом оптимизации моей "гнилой конструкции"
ResX писал(а):
ну как же можно сравнивать инкремент значения адреса переменной с "перелопачиванием" памяти?

А че сравнивать, вот результат на лицо
Код:
1
2
3
4
5
6
string.s = "PureBasic"
INC string                                ; сдвигаем строку на один символ влево (1)
Debug string                          ; = "ureBasic"
string = "PureBasic"
string = Right(string, Len(string)-1)     ; сдвигаем строку на один символ влево (2)          
Debug string                          ; = "ureBasic"


В первом случае при написании исходника нужно 10 раз тыкнуть по клаве, во втором посчитайте сами. Ну и в скомпиленном коде - в первом случае 6 байт, во втором возмите отладчик (OllyDbg) и посмотрите.
А результат в обоих случаях одинаковый. Нам ведь не важно по какому адресу лежит переменная, а важно что в ней содержится

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


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

Зарегистрирован: Сб авг 18, 2007 6:26 pm
Сообщений: 605
Откуда: Северодвинск/Питер
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Пункты репутации: 0
pablov писал(а):
А результат в обоих случаях одинаковый. Нам ведь не важно по какому адресу лежит переменная, а важно что в ней содержится

Вообще-то ResX прав. Это совершенно неэквивалентные операции, хотя результат один и тот же. Когда ты делаешь Right, ты создаёшь копию исходной строки без одного символа. Мало того, что тратится куча тактов процессора, но ещё и возникает фрагментация памяти. Когда ты изменяешь значение указателя на переменную, никакого копирования не происходит.

_________________
http://www.youtube.com/watch?v=XHosLhPEN3k


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

Зарегистрирован: Ср янв 14, 2009 4:12 pm
Сообщений: 2002
Благодарил (а): 12 раз.
Поблагодарили: 101 раз.
Пункты репутации: 43
All_Creater дык я согласен что
All_Creater писал(а):
Это совершенно неэквивалентные операции
но топик я поднимал не для сравнения операций, а об асм. вставках.
Цитата:
Когда ты делаешь Right, ты создаёшь копию исходной строки без одного символа. Мало того, что тратится куча тактов процессора, но ещё и возникает фрагментация памяти. Когда ты изменяешь значение указателя на переменную, никакого копирования не происходит.

Вот, вот и я про это. Если есть вожмоность изменить значение указателя (а эта взможность в PureBasic нам дана), зачем тратить "кучу тактов процессора," и пр. и пр.
Вот, к примеру ты парсишь строку. Нужно делать сдвиг строки. И какой способ ты предпочтешь? Начальное значение всегда можно сохранить во временной переменной.

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


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

Зарегистрирован: Пт фев 20, 2009 12:57 pm
Сообщений: 1717
Откуда: Алматы
Благодарил (а): 16 раз.
Поблагодарили: 47 раз.
Пункты репутации: 5
кончайте умничать. я вот юзал и райт и лефт - теперь меня начинает мучать совесть, что моя программа излишне ресурсно требовательна.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн дек 28, 2009 6:54 am 
Не в сети
МОДЕРАТОР

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

У меня вот такой практический вопрос по существу - является ли код с ассемблерными вставками кросплатформенным или синтаксис FASMа для МАКа и винды или никсов разный? Сам проверить не могу - кроме Винды на компе ни чего не держу.


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

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

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


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

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6413
Благодарил (а): 21 раз.
Поблагодарили: 201 раз.
Пункты репутации: 52
Пётр писал(а):
Асм, он не зависим от платформы, а зависим от проца!

Ну я бы так не сказал - к примеру под DOS один ассемблер, под Видну уже другой, 16 разрядный - 32 разрядный, процессоры то одинаковые...
ну вот ты под Линем можешь этот пример откомпилировать без переделок?

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


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

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11336
Благодарил (а): 4 раз.
Поблагодарили: 443 раз.
kvitaliy писал(а):
ну вот ты под Линем можешь этот пример откомпилировать без переделок?
Да, только приходится избавлятся от WinAPI и функций друпии.

Вот эти примеры прекрастно компилятся и работают под линукс
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string.s=Space(469440)
temp.b
Dim mass.b(78239 ,5)
time=ElapsedMilliseconds()
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=ElapsedMilliseconds()-time
MessageRequester("o_O", "Время с ASM вставкой:  "+ Str(time))





Код:
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
 
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))
EndProcedure
Procedure Button_2_OnEvent(EventType.l)
  a= HexStrToNumber(GetGadgetText(#String_0))
  MessageRequester("o_O", "Return:  " + Str(a))
EndProcedure
Procedure Button_3_OnEvent(EventType.l)
  a.s= StrToHexVal(GetGadgetText(#String_0))
  MessageRequester("o_O", "Return:  " +a)
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


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


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

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6413
Благодарил (а): 21 раз.
Поблагодарили: 201 раз.
Пункты репутации: 52
Пётр писал(а):
Да, только приходится избавлятся от WinAPI и функций друпии.


Именно это я и имел в виду. Значит все же совместимо, что конечно радует!

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


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

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


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

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


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

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