purebasic.info

PureBasic forum
Текущее время: Сб июл 21, 2018 4:25 pm

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




Начать новую тему Ответить на тему  [ Сообщений: 25 ]  На страницу Пред.  1, 2
Автор Сообщение
 Заголовок сообщения: Re: Hex2Dec
СообщениеДобавлено: Вс дек 03, 2017 9:14 pm 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 571
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
kvitaliy писал(а):
Volkoff писал(а):
Потому что нужно для частного случая в промышленных масштабах. Вот так все банально.

Мой мозг просто не может смоделировать ситуацию, когда это действительно нужно быстро. Ведь все в курсе, что компы считают не в десятичной системе и даже не в HEX, а в двоичной?
Кинь простой пример, где нужно в промышленном масштабе быстро, на ASMe преобразовать Hex2Dec, а то я от любопытства помру, заодно и Сергейчик сможет тебе с АСМом помочь, он в нём большой дока.

Сергейчик он да сможет помочь когда разберётся с задачей(ведь где описание её в теме?)
PS:А пока Сергейчик налил 50 г коньяка и читает форум(потому как пришёл с калыма и в воскресенье заработал бабло на которое будет неделю жить :) )
И так и навязывается каждый раз вопрос к тп.ст. с ником волкоф про командер(не вы ли его писали?)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Hex2Dec
СообщениеДобавлено: Вс дек 03, 2017 9:51 pm 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 571
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
Начинаю по тихому въезжать..
А хде в в первом посте замечание на не указание возвращаемого параметра?
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
Procedure Hex2Dec(ValAddr.l, BytesLen.l)
 
  ProcedureReturn Val("$"+PeekS(ValAddr, BytesLen))
 
EndProcedure
 
Val1.s = "007714A3"
Val2.s = "03"
 
Debug RSet(Hex(Hex2Dec(@Val1, 8),#PB_Long),8,"0")
Debug RSet(Hex(Hex2Dec(@Val2, 2),#PB_Byte),2,"0")
 
 
 



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Hex2Dec
СообщениеДобавлено: Ср дек 06, 2017 3:28 am 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 571
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
Может так сойдёт,до 4 байт и не учитывает спереди $,0 и в конце h. :D
Код:
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
 
Procedure.i HexDec_UTF_16(*mem);преобразует строку символов utf16(до 8) в  в dec
!push esi
!push ebx
!mov dword esi,[esp+12]
!cmp word [esi],0h
!jz wyxod2
;
!MOVZX dword eax,byte[esi]
!mov byte al,[tabliza+eax-48]
;
!cikl2:
!cmp word [esi+2],0h
!jz wyxod2
;
!MOVZX dword ebx,byte[esi+2]
!mov byte bl,[tabliza+ebx-48]
!shl dword eax,4
!or byte al,bl
!add dword esi,2
!jmp cikl2
;
!wyxod2:
!pop ebx
!pop esi
;
!retn 4
EndProcedure
 
Debug Hex(HexDec_UTF_16(@"45"))
Debug Hex(HexDec_UTF_16(@"ffffff2A"))
Debug Hex(HexDec_UTF_16(@"1a"))
 
 
 
DataSection
 !tabliza:                        
  !db 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0
  !db 0,10,11,12,13,14,15,0,0,0,0,0,0
  !db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  !db 0,0,0,0,10,11,12,13,14,15
EndDataSection
 
 



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Hex2Dec
СообщениеДобавлено: Ср дек 20, 2017 2:45 am 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 571
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
В первом варианте регистр ебх излишний,в этом нет проверки на больше 16 символов для перевода
PS:Процедура для ввода в калькулятор мне сойдёт,а вот трассировщики?. :roll:
Код:
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
 
;Автор (с) Сергейчик
Global tt.q
Global t.q
Procedure UTF16_HexDec(*mem,*peremennay);преобразует 16 строковых  символа utf16(нет проверки на большее) по адресу переменной с типом q(8байт)
!push esi
!push edi
!mov dword esi,[esp+12]
!mov dword edi,[esp+16]
;предварительно обнулим переменную
!mov dword[edi],0h
!mov dword[edi+4],0h
!
!cmp word [esi],0h;есле строка пустая то выходим
!jz wyxod
;;Есть символы для перевода
;;
!MOVZX dword eax,byte[esi]
!mov byte al,[tabliza+eax-48]
!mov byte[edi],al
;
!cikl1:
!cmp word [esi+2],0h
!jz wyxod
;
!MOVZX dword eax,byte[esi+2]
!mov byte al,[tabliza+eax-48]
!shl dword [edi],4
!or byte[edi],al
!add dword esi,2
!
!test dword[edi],0F0000000h;Если edi = 4baita и ещё есть символы для перевода переходим на новую обработку
!jnz bolhe4bait
;;ещё не достигли 4 байт
!jmp cikl1
;!jmp wyxod
;
!bolhe4bait:
!cikl3:
!cmp word [esi+2],0h
!jz wyxod
;
!shl dword [edi+4],4;сдвиг 2-e 32bita
!mov byte al,[edi+3]; в al 3байт
!shr byte al,4;сдвиг для получения маски
!or byte[edi+4],al;установка в полубайт значение переноса
!shl dword [edi],4; теперь сдвиг младшего dword
 
!MOVZX dword eax,byte[esi+2]
!mov byte al,[tabliza+eax-48]
!or byte[edi],al
!add dword esi,2
!jmp cikl3
!
 
!wyxod:
!pop edi
!pop esi
;
!retn 8
DataSection
 !tabliza:                        
  !db 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0
  !db 0,10,11,12,13,14,15,0,0,0,0,0,0
  !db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  !db 0,0,0,0,10,11,12,13,14,15
EndDataSection
EndProcedure
 
 
 
UTF16_HexDec(@"FA8EDB35FFcFFA",@tt)
Debug tt
UTF16_HexDec(@"a456c7be5dfa46",@t)
Debug t
tt+t
Debug tt
 



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Hex2Dec
СообщениеДобавлено: Ср дек 20, 2017 6:05 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Сб июл 18, 2009 8:25 am
Сообщений: 812
Откуда: Нерезиновая
Благодарил (а): 21 раз.
Поблагодарили: 4 раз.
Пункты репутации: 0
Спасибо за пример.
Хотя разматывать такие дела на 64 битах это то еще удовольствие... На 32- битной ХР в силу естественных ограничений все сильно проще идет :)

Кстати изначальная задача имеет лучшее решение, вот например кодес от Pablov (с минимальными изменениями) дополнительно проверяет валидность формата и работает быстрее (даже если проверки не выпиливать).

Код:
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
Procedure.l hex2dec(str.s)
 
  ; Процедура конвертирует HEX строку в десятичное число. В случае успеха, возвращает десятичное число
  ; В сучае пустой строки, или не HEX фрмата возвращает -1
 
 ;LOCALS
  Protected Result.l
  EnableASM
     MOV eax, str
     XOr ecx, ecx
     XOr ebx, ebx
     MOV bl, byte[eax]
     CMP bl, 0              ; проверяем пустая строка или нет
     JE _3
  !_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 -1
  ! _2:  
     Or  ecx, ebx
     INC eax
     MOV bl, byte[eax]
     CMP bl, 0              ; проверяем конец строки
     JE endproc
     SHL ecx, 4
     JMP _loop
  !endproc:
     MOV Result, ecx
     ProcedureReturn Result
     DisableASM
EndProcedure



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Hex2Dec
СообщениеДобавлено: Чт дек 21, 2017 4:01 am 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 571
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
Volkoff писал(а):
Спасибо за пример.
Хотя разматывать такие дела на 64 битах это то еще удовольствие... На 32- битной ХР в силу естественных ограничений все сильно проще идет :)

Кстати изначальная задача имеет лучшее решение, вот например кодес от Pablov (с минимальными изменениями) дополнительно проверяет валидность формата и работает быстрее (даже если проверки не выпиливать).

Код:
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
Procedure.l hex2dec(str.s)
 
  ; Процедура конвертирует HEX строку в десятичное число. В случае успеха, возвращает десятичное число
  ; В случае пустой строки, или не HEX фомата возвращает -1
 
 ;LOCALS
  Protected Result.l
  EnableASM
     MOV eax, str
     XOr ecx, ecx
     XOr ebx, ebx
     MOV bl, byte[eax]
     CMP bl, 0              ; проверяем пустая строка или нет
     JE _3
  !_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 -1
  ! _2:  
     Or  ecx, ebx
     INC eax
     MOV bl, byte[eax]
     CMP bl, 0              ; проверяем конец строки
     JE endproc
     SHL ecx, 4
     JMP _loop
  !endproc:
     MOV Result, ecx
     ProcedureReturn Result
     DisableASM
EndProcedure


Так ваш пример не рабочий в юникоде :roll:
И зачем было создавать переменную ?
К тому же нет сохранённых регистров и тем самым такую процедуру не всуниш в код на асме не сохранив опять таки сначала регистры и мало вероятно что её можно скомпилить в dll?
Код:
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
 
Procedure.l hex2dec(STR.s)
 
  ; Процедура конвертирует HEX строку в десятичное число. В случае успеха, возвращает десятичное число
  ; В сучае пустой строки, или не HEX фрмата возвращает -1
    EnableASM
     MOV esi, STR
     XOR eax, eax
     XOR ebx, ebx
     MOV bl, byte[esi]
     CMP bl, 0              ; проверяем пустая строка или нет
     JE _3
  !_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:
  !mov dword eax,-1
  !endproc:
 ProcedureReturn
 ;!retn 4
  ! _2:  
     OR  eax, ebx
     INC esi
     MOV bl, byte[esi]
     CMP bl, 0              ; проверяем конец строки
     JE endproc
     SHL eax, 4
     JMP _loop
     DisableASM
EndProcedure
 



Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Hex2Dec
СообщениеДобавлено: Чт дек 21, 2017 3:17 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Сб июл 18, 2009 8:25 am
Сообщений: 812
Откуда: Нерезиновая
Благодарил (а): 21 раз.
Поблагодарили: 4 раз.
Пункты репутации: 0
Сергейчик писал(а):
Так ваш пример не рабочий в юникоде :roll:

Почитайте тему, искалось узкоспециализированное решение под ASCII х32 в конкретной задаче и не более, о чем неоднократно упоминалось.
Хотите написать абсолютно универсальный вариант для всех случаев жизни, почему нет, если он буде быстрее я и для своих задач его возьму :)
Задача простая написать проблем нет, искал чтобы не велосипедить в очередной раз...

Ну а так, в вашем "оптимизированном" варианте разница по факту будет в 4 инструкции и экономит незначительное количество тактов процессора, хотя на объемах прирост небольшой будет.
И кстати:
Код:
1
2
!mov dword eax,-1
ProcedureReturn

и
Код:
1
ProcedureReturn -1

компилятор соберет одинаково
Я привел код Pablov-а практически без изменений (исправив лишь возврат с нуля на FFFFFFFF при валидном нулевом вхождении).
Для скорости его нужно использовать в инлайн виде (что очевидно), иначе компилятор будет добавлять в процедуру вызовы MSVCRT.strlen, KERNEL32.HeapAlloc и KERNEL32.HeapFree
Поэтому просто передаем указатель и делаем !MOV eax, [esp+4], расставляем ! перед инструкциями и mov eax, ecx в конце. Получаем прирост скорости ~ в 10 раз.

Тест на 10000000 итераций высокоточным таймером:
Код:
1
2
3
4
5
39040 - оригинал функции от Pablov
37355 - ваш вариант функции
7487  - стандартная функция PB
3754  - функция что предложил изначально я
3743  - инлайн вариант функции от Pablov



Не будем ломать копья, работает и то хорошо :)


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

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6327
Благодарил (а): 19 раз.
Поблагодарили: 189 раз.
Пункты репутации: 48
И всё таки разбирает любопытство, ну зачем? Где может понадобиться 10000000 итераций подряд и именно эта функция будет самым узким местом в программе?

_________________
read-only


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Hex2Dec
СообщениеДобавлено: Чт дек 21, 2017 9:21 pm 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 571
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
kvitaliy писал(а):
И всё таки разбирает любопытство, ну зачем? Где может понадобиться 10000000 итераций подряд и именно эта функция будет самым узким местом в программе?

По большому счёту тоже согласен,зачем?
Предположу реверсинжиниринг ,типа перевести hex в dec (ну лично мне не нравится такая конструкция в трассировщиках и отладчиках в hex,так как для понимания индекса нужно сначала перевести в dec(я же не вундеркинд что бы понять что DC5E =в DEC это смещение в 56414)и нужно сначала типо в калькулятуре преобразовать значение)
PS:Да и странно то что когда говорит автор темы что да инструкций процу меньше на пару штук но все равно в проалётё


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

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 571
Благодарил (а): 2 раз.
Поблагодарили: 32 раз.
Пункты репутации: 9
Может кому пригодится для utf16 :roll:
Код:
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
 
Procedure.i UTF16Hex_vDec(*STR)
    !push esi
    !push ebx
    !MOV dword esi,[esp+12]
    ;
    !cmp word [esi],0h
    !Jz _3
    !XOR eax,eax
   !_loop:
   !MOV byte bl,byte[esi]
    !CMP bl,39h;>9;
    !JA  _1
    !CMP byte bl,30h; <0          
    !Jl  _3
    !SUB byte bl,30h
    !OR byte al,bl
    !cmp word[esi+2],0h
    !JZ endproc
    !add dword esi,2
    !SHL eax, 4
    !JMP _loop
  !_1:  
    !CMP byte bl,46h;; >F
    !JA  _4
    !CMP bl,41h;<A          
    !Jl  _3
    !SUB byte bl,37h
    !OR byte al,bl
    !cmp word[esi+2],0h
    !JZ endproc
    !add dword esi,2
    !SHL eax, 4
    !JMP _loop
  !_4:
   !CMP byte bl,66h;>f
    !JA  _3
    !CMP bl,61h;<a          
    !Jl  _3
    !SUB byte bl,57h
    !OR byte al,bl
    !cmp word[esi+2],0h
    !JZ endproc
    !add dword esi,2
    !SHL eax,4
    !JMP _loop
   !_3:
  !mov dword eax,-1
 !endproc:
 !pop ebx
  !pop esi
  ProcedureReturn
EndProcedure
   
Debug  UTF16Hex_vDec(@"FA8EFFcF")
Debug  UTF16Hex_vDec(@"a4c7be5d")
 


Вариант №2
Код:
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
 
Procedure.i UTF16Hex_vDec(*STR)
    !push esi
    !push ebx
    !MOV dword esi,[esp+12]
    ;
    !cmp word [esi],0h
    !Jz _3
    !XOR eax,eax
    !jmp ghj
   !_loop:
   !add dword esi,2
    !SHL eax, 4
    !ghj:
   !MOV byte bl,byte[esi]
    !CMP bl,39h;>9;
    !JA  _1
    !CMP byte bl,30h; <0          
    !Jl  _3
    !SUB byte bl,30h
    !OR byte al,bl
    !cmp word[esi+2],0h
    !JnZ _loop
    !pop ebx
    !pop esi
  ProcedureReturn
  !_1:  
    !CMP byte bl,46h;; >F
    !JA  _4
    !CMP bl,41h;<A          
    !Jl  _3
    !SUB byte bl,37h
    !OR byte al,bl
    !cmp word[esi+2],0h
    !JnZ _loop
    !pop ebx
    !pop esi
  ProcedureReturn
  !_4:
   !CMP byte bl,66h;>f
    !JA  _3
    !CMP bl,61h;<a          
    !Jl  _3
    !SUB byte bl,57h
    !OR byte al,bl
    !cmp word[esi+2],0h
    !JnZ _loop
    !pop ebx
    !pop esi
  ProcedureReturn
  !_3:
  !mov dword eax,-1
  !pop ebx
  !pop esi
  ProcedureReturn
EndProcedure
 
Debug  UTF16Hex_vDec(@"FA8EFFcF")
Debug  UTF16Hex_vDec(@"a4c7be5d")
 



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

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


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

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


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

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