|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Авг 11, 2004 12:33:51 Требуется оптимизировать по скорости перевод ASCII строки вида sign1 = 5678ff45::::::0011,0, sign 2= 45454500::ff,0,0 (строка оканчивается на два нуля!) в которой могут присутствовать пробелы и табуляция в строку 'sign1',0,5678FF450000000011 , где sign1 осталось в ASCII, всё остальное переведено в HEX причем получаемая строка должна всё время писаться сначала буфера buff Т.е. символы :::: должны заменяться на 0000, в идеале нужно чтоб любые не HEX символы в ASCII представлении заменялись бы 0 нулём. Я тут набросал первоначальный вариант, но что-то у меня уже крышу сносит, кажется я не все учёл, а уж что не оптимально так это точно. mov esi, src
@loop:
mov edi, buff
mov al, BYTE [esi]
cmp al, 20h ; пробел
je @skip
cmp al, 09h ; табуляция
je @skip
@parse:
test al, al
jz @test
cmp al, '='
je @found
mov BYTE [edi], al
inc esi
inc edi
mov al, BYTE [esi]
jmp @parse
@found:
mov BYTE [edi], 0
inc edi
inc esi
@loop3:
mov ecx, 2
; xor bl, bl
@loop2:
lodsb
test al, al
jz @test2
cmp al, 20h ; пробел
je @loop2
cmp al, 09h ; табуляция
je @loop2
shl ebx, 4
cmp al, 3Fh+1
sbb edx, edx
cmp al, 3Ah
adc edx, 0
cmp edx, -1
sbb edx, edx
and eax, edx
jz @F
cmp al, 'f'+1
sbb edx, edx
cmp al, 'a'
adc edx, 0
and edx, 'A'-'a'
add al, dl
cmp al, 'F'+1
sbb edx, edx
cmp al, 'A'
adc edx, 0
and edx, -07h
add al, dl
xor al, 030h
@@:
or ebx, eax
loop @loop2
mov BYTE [edi], bl
inc edi
jmp @loop3
;--------------------------------------------------------
@skip:
inc esi
jmp @loop
@test:
mov al, BYTE [esi+1]
@test2:
test al, al
jnz @loop |
|
|
Дата: Авг 11, 2004 13:10:56 Asterix перевод ASCII строки вида ... в строку ... Мне не совсем понятна твоя запись. Можно увидеть исходную строку и результирующую в шестнадцатеричном виде, байты отделены пробелами? И если можно, то пример содержащий пробелы и табуляции и как с ними надо поступисть. |
|
|
Дата: Авг 11, 2004 13:42:31 А пример можно? |
|
|
Дата: Авг 11, 2004 13:46:21 · Поправил: Asterix Исходная строка, оканчивающаяся двумя 0 нулями. Каждая подстрока в исходной строке в свою очередь оканчивается 0 нулём. Вывод нужно делать в один и тот же буфер, с его начала, для каждой подстроки. 00550000 73 69 67 6E 31 3D 39 41 sign1=9A 00550008 20 46 46 20 46 46 20 30 FF FF 0 00550010 30 20 30 30 20 39 41 20 0 00 9A 00550018 46 46 46 46 20 30 30 30 FFFF 000 00550020 30 20 35 35 38 39 20 45 0 5589 E 00550028 35 33 31 20 3A 3A 3A 3A 531 :::: 00550030 46 46 30 30 30 30 00 73 FF0000.s 00550038 69 67 6E 20 32 3D 41 31 ign 2=A1 00550040 3A 3A 3A 3A 3A 3A 3A 3A :::::::: 00550048 43 31 3A 3A 3A 3A 41 33 C1::::A3 00550050 3A 3A 3A 3A 3A 3A 3A 3A :::::::: 00550058 38 33 3A 3A 3A 3A 3A 3A 83:::::: 00550060 3A 3A 37 35 3A 3A 35 37 ::75::57 00550068 35 31 33 33 43 30 42 46 5133C0BF 00550070 00 73 69 67 6E 33 3D 41 .sign3=A 00550078 31 3A 3A 3A 3A 3A 3A 3A 1::::::: 00550080 3A 43 31 3A 3A 3A 3A 41 :C1::::A 00550088 33 3A 3A 3A 3A 3A 3A 3A 3::::::: 00550090 3A 35 37 35 31 33 33 43 :575133C 00550098 30 42 46 3A 3A 3A 3A 3A 0BF::::: 005500A0 3A 3A 3A 42 39 3A 3A 3A :::B9::: 005500A8 3A 3A 3A 3A 3A 33 42 43 :::::3BC 005500B0 46 37 36 00 00 00 00 00 F76..... Это результирующая строка, которая должна выводится для каждой подстроки в строке: 00401008 73 69 67 6E sign 00401010 31 00 9A FF FF 00 00 9A 1.љяя..љ 00401018 FF FF 00 00 55 89 E5 31 яя..U‰е1 00401020 00 00 FF 00 00 ..я.. > И если можно, то пример содержащий пробелы и табуляции и как с ними надо поступисть Пробелы до начала строки должны проskip'ываться, пробелы в названии sign 1 должны оставляться. sign 1 = 9A FF FF 00 00 9A FFFF 0000 5589 E531 ::::FF0000 | | |_этот не нужен |____|____|эти пробелы не нужны | | | |_этот нужен | | | |_этот пробел не нужен Хотя практически получается что строка возле = не содержит пробелов на это нельзя рассчитывать. |
|
|
Дата: Авг 11, 2004 14:23:37 · Поправил: Black_mirror Asterix Если внутри сигнатуры могут содержаться нули, как ты определишь где начинается следующая подстрока? Или мы записываем в буфер первую подстроку, обрабатываем, а затем записываем следующую? И еще вопрос: как обрабатывать последний символ сигнатуры если их количество нечетное? |
|
|
Дата: Авг 11, 2004 15:10:49 Black_mirror Внутри сигнатуры нулей 00h нет, есть только '0'=30h те нули что там встречаются это концы подстрок В исходном буфере все подстроки идут подряд: подстрока1,0,подстрока2,0,подстрока3,0,0 <-это конец т.к. два нуля. Условимся что четное, т.е. сигнатура, после = будет состоять из четного числа байт(не считая пробелы и табуляцию, с ними может быть и не четное), иначе я вобще не понимаю как это можно правильно перевести из ASCII в HEX. |
|
|
Дата: Авг 11, 2004 15:20:37 · Поправил: Asterixsrc db 'sign1 = 9A FF FF 00 00 9A FFFF 0000 5589 E531 ::::FF0000',0
db 'sign 2=A1::::::::C1::::A3::::::::83::::::::75::575133C0BF',0
db 'sign3 =A1::::::::C1::::A3::::::::575133C0BF::::::::B9::::::::3BCF76',0,0 |
|
|
Дата: Авг 11, 2004 17:15:15 Asterix Я не правильно задал вопрос, если после преобразования подстроки в сигнатуру, внутри сигнатуры окажутся нули, то как ты определишь где начинается следующая сигнатура? И еше напиши пожалуйста какие символы в подстроке вообще игнорируются и из каких может состоять имя. PS: Если бы в части подстроки, которая представляет сигнатуру не было бы символов которые нужно игнорировать, то можно было бы преобразовывать сразу по 4 или по 8 символов. |
|
|
Дата: Авг 11, 2004 17:37:37 · Поправил: Asterix Black_mirror > Я не правильно задал вопрос, если после преобразования подстроки в сигнатуру, внутри сигнатуры окажутся нули, то как ты определишь где начинается следующая сигнатура? Вобще-то я планировал подсчитывать размер сигнатуры в момент преобразования, но здесь пока не реализовал. > то как ты определишь где начинается следующая сигнатура? Следующая сигнатура будет вписываться в этот же буфер с самого начала, перекрывая предыдущую, потому что после получения сигнатуры и ее длины эти параметры будут передаваться в процедуру и по результату работы процедуры будет решаться парсить ли src дальше. > И еше напиши пожалуйста какие символы в подстроке вообще игнорируются и из каких может состоять имя. В имени могут быть любые символы кроме = , т.к. равно определяет конец имени сигнатуры и начало собственно ее самой, даже пробельные, в сигнатуре любые не HEX символы, кроме пробельных, должны заменяться на нули, в данном случае это :: дают 00 т.е. нулевой байт, пробельные пропускаться и не входить в итоговую сигнатуру в hex представлении. В результате преобразования мне нужно получить:
поинтер на первый байт сигнатуры длину сигнатуры |
|
|
Дата: Авг 11, 2004 18:58:31 · Поправил: Black_mirror Asterix Вот как можно по 4 символа сразу обрабатывать: Четыре символа находящиеся в регистре eax рассматриваются как 16-ричные цифры(биты 7:0 - первая цифра, 31:24 - последная цифра, все что не является цифрой заменяется на 0) и переводятся в два байта(al байт полученный из бит 7:0(старшая цифра) и 15:8(младшая цифра), ah - байт полученный из 23:16 и 31:24). Под bit7 имеетются ввиду старшие биты каждого байта регистра. hextonum:;(eax - four char):ax - num ;A..F -> a..f mov ecx,40404040h ;перевод букв в верхний регист and ecx,eax ;также могут буть заменены и некоторые другие символы shr ecx,1 ;но на правильность работы функции это никак не влияет not ecx and eax,ecx ;char -> BCD lea edx,[eax-'0000'] or edx,80808080h ;для избежания распространения переноса в соседние байты lea ebx,[edx-'AAAA'+'0000'] ;принадлежит ли байт диапазону A..F lea ecx,[edx-'GGGG'+'0000'] xor ebx,ecx ;bit7=1 if A..F lea ecx,[edx-0A0A0A0Ah] ;принадлежит ли байт диапазону 0..9 xor ecx,edx ;bit7=1 if 0..9 not eax ;bit7=1 if not digit xor ecx,ebx ;буква или цифра and eax,ecx ;bit7=1 if digit ;if A..F then sub 7 and ebx,80808080h ; сдвигаем интервал A..F к интервалу 0..9 shr ebx,4 sub edx,ebx shr ebx,3 add edx,ebx ;create mask and eax,80808080h ;обнуляем все символы не цифры mov ecx,eax shr ecx,7 sub eax,ecx and eax,edx ;not digit -> 0 ;BCD -> num mov edx,eax ;в каждом байте теперь по одной 16-ричной цифре shl edx,12 add eax,edx mov al,ah rol eax,8 xchg al,ah ret Нужно только эффективный метод выкидывания пробелов придумать. PS: Кстати без всяких if'ов и переходов! |
|
|
Дата: Авг 11, 2004 21:53:11 Black_mirror > Нужно только эффективный метод выкидывания пробелов придумать. Невыполнимо наверно :-( А что до твоего кода то я практически ничего не понял, думаю тут нужно на бумажке себе всё расписать что на каком шаге происходит. Давай посмотрим по кускам, вот здесь cmp al, 20h ; пробел je @skip cmp al, 09h ; табуляция je @skip и test al, al jz @test2 cmp al, 20h ; пробел je @loop2 cmp al, 09h ; табуляция je @loop2 Может можно как-то оптимизировать чтоб остался только один переход? |
|
|
Дата: Авг 12, 2004 00:08:11 · Поправил: Black_mirror Asterix Выкинуть не сложно, только эти переходы срабатывают не часто, так что наверно лучше с ними. mov ah,al xor eax,2009h lea edx,[eax-101h] xor edx,eax and edx,eax xor al,9 and ebx,8080h jnz .skip или в лоб: cmp al,21h sbb ebx,ebx cmp al,20h adc ebx,0 cmp al,10 sbb ebx,0 cmp al,9 adc ebx,0 jnz .skip А для моей функции требуется собрать в eax четыре непробельных символа и она их преобразует в 2 байта сигнатуры. Я еще там малость коментариев дописал. Для второго участка кода одним переходом не обойтись, там метки 2 разные метки. |
|
|
Дата: Авг 12, 2004 00:53:16 Black_mirror > Для второго участка кода одним переходом не обойтись, там метки 2 разные метки Точно, это не доглядел когда постил. > А для моей функции требуется собрать в eax четыре непробельных символа и она их преобразует в 2 байта сигнатуры. Я еще там малость коментариев дописал. Спасибо, с комментариями немного стало понятней. Ладно, а как функция сработает если 4-е байта не найдется в конце сигнатуры ? А как проскипать пробелы я кажется понял типа: mov ecx, 4 @@: lodsb test al, al jz cmp al, 20h je @B cmp al, 09h je @B shl eax, 8 loop @B Для быстроты конечно нужно будет lodsb и loop заменить. |
|
|
Дата: Авг 12, 2004 00:59:37 Asterix Ладно, а как функция сработает если 4-е байта не найдется в конце сигнатуры ? Все зависит от того, что ты ей вместо недостающих байт подсунешь. |
|
|
Дата: Авг 12, 2004 01:11:54 Да, ещё, как при обработке по 4-е байта посчитать заодно размер сигнатуры? Хотя сейчас кажется придумал.. > Все зависит от того, что ты ей вместо недостающих байт подсунешь. Если нули? Кстати если твоя функция припишет в конец итоговой сигнатуры лишние нули и учтет это при подсчёте длины сигнатуры, то это, вобщем-то, на результат работы функции, работающей с полученной сигнатурой не отразится т.к. нули там считаются за любой байт и условие всегда будет верно. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.059 |