Хотелось бы оптимизировать.. Или может кто предложит другую схему реализации. Строка в буфере может быть и длиннее, т.е. флагов может быть больше. Естественно код специально написан для примера, но смысл думаю понятен. Код (Text): .DATA Flag dd 0 Flag1 dd 0 Flag2 dd 0 Flag3 dd 0 Flag4 dd 0 Buff db "10000",0 .CODE start: mov esi, OFFSET Buff .IF BYTE PTR [esi] == '1' inc Flag1 inc Flag .ENDIF .IF BYTE PTR [esi+2] == '1' inc Flag2 inc Flag .ENDIF .IF BYTE PTR [esi+3] == '1' inc Flag3 inc Flag .ENDIF .IF BYTE PTR [esi+4] == '1' inc Flag4 inc Flag .ENDIF .IF (Flag) invoke MessageBox, 0, OFFSET Buff, 0, 0 .ENDIF
Ну вот, особо не вдаваясь в суть: Код (Text): Flag dd 0 AllFlag rb maxsize mov esi,buf xor edx,edx dec edx @@: inc edx lodsb sub al,'1' jnz @B inc [Flag] inc byte [AllFlag+edx] jmp @B Только надо проверку на размер сделать, а то крутиться до посинения будет.
n0p > особо не вдаваясь в суть Нужно было вникнуть в суть, потому что код у тебя не правильный, как мне показалось.. Добавлено Ага, исправил уже значит..
Asterix Флаги это счётчики или у них всего 2 значения? Во втором случае можно хранить флаги в битовом массиве, а для установки MMX или SSE2 использовать: Код (Text): movq mm1,[t] movq mm0,[buf] pcmpeqb mm0,mm1 pmovmskb eax,mm0 mov [flags],al movq mm0,[buf+8] pcmpeqb mm0,mm1 pmovmskb eax,mm0 mov [flags+1],al ... t db '11111111' Если флагов не более 32 то для проверки Flag можно использовать сравнение flags с 0. А если Flag это счётчик то можно использовать алгоритмы для подсчёта числа бит, которые были на форуме.
Код (Text): Flag db 0 Flag1 db 0 Flag2 db 0 Flag3 db 0 Flag4 db 0 mov edi, Flag mov esi, Buff mov al,'1' cmp byte[esi],al setz dl mov [edi+1],dl ; Flag1 or [edi],dl cmp byte[esi+2],al setz dl mov [edi+2],dl ; Flag2 or [edi],dl cmp byte[esi+3],al setz dl mov [edi+3],dl ; Flag3 or [edi],dl cmp byte[esi+4],al setz dl mov [edi+4],dl ; Flag4 or [edi],dl jz Flag_false invoke MessageBox, 0, Buff, 0, 0 Flag_false: dl можно заменить на ah. Флаги заменены на байты - для экономии Вообще, напрашивается решение отказаться от всяких +2, +3, +4 и засунуть в цикл, добавив счётчик ecx и адресовать так: Код (Text): cmp byte[esi+ecx],al setz dl mov [edi+ecx],dl ; Flag NN or [edi],dl inc ecx ЗЫ: Что-то я думаю долго, уже понаписали тут
Кстати, если длинна строки не превышает 32 символов, то можно регистр под это дело выдать и ему биты менять. Получится красиво и не надо флаги в памяти хранить. Но ограничение по длине.
Кстати, никто не заметил что я не проверяю BYTE PTR [esi+1] - это не описка, так что цикл меня не особенно устраивает.
Asterix Ну можно проверять нулевой, пропускать первый и дальше циклом все остальные Без цикла не удастся сделать код для неопределенной длины строки.
Asterix > Какие проблемы, отдельно проверяй первое условие: Код (Text): flag_number = 4 Flag db 0 rb flag_number mov edi, Flag mov esi, Buff mov al,'1' mov ecx,flag_number cmp byte[esi],al setz dl mov [edi+1],dl ; Flag1 or [edi],dl loop: cmp byte[esi+ecx+1],al setz dl mov [edi+ecx],dl ; Flag NN or [edi],dl dec ecx jnz loop cmp [edi],cl jz Flag_false invoke MessageBox, 0, Buff, 0, 0 Flag_false:
А зачем вообще эти Flag1-Flag4, сам buffer напрашивается на его использование в качестве флагов, а конкретно для этого кода похоже работает и так: Код (Text): ;=============================================== buffer db "10000",0 size = $-buffer ;=============================================== mov esi,buffer-1 mov ecx,size-1 mov byte [esi+2],'0' @@: inc esi cmp byte [esi],'1' jz msgbox loop @B ... msgbox: invoke MessageBox,0,buffer,buffer,0 ;===============================================
S_T_A_S_ > Какие проблемы, отдельно проверяй первое условие Всё-равно проблемы есть, т.к. действия между .IF/.ENDIF в моём случае не ограничиваются только лишь установкой флагов, т.е. могут быть дополнительные проверки, вызываться другие функции и лишь после этого выставляться флаги.
Asterix Тема этого топика подозрительно похожа на тему этого топика: http://www.wasm.ru/forum/index.php?action=vthread&forum=3&topic=6111
captain cobalt Да, только теперь количество флагов увеличилось и я стал путаться в моём коде, хотелось что-то изменить
Сделал вот так, пусть не оптимально, зато наглядно Код (Text): Flag dd 0 Flag1 dd 0 Flag11 dd 0 Flag2 dd 0 Flag3 dd 0 Flag4 dd 0 Buff db "10000",0 .CODE start: mov esi, OFFSET Buff mov edi, OFFSET Flag mov ebx, OFFSET Flag1 .IF BYTE PTR [esi] == '1' inc DWORD PTR [ebx] inc DWORD PTR [edi] .ENDIF .IF BYTE PTR [esi+2] == '1' inc DWORD PTR [ebx+2*(SIZEOF DWORD)] inc DWORD PTR [edi] .ENDIF .IF BYTE PTR [esi+3] == '1' inc DWORD PTR [ebx+3*(SIZEOF DWORD)] inc DWORD PTR [edi] .ENDIF .IF BYTE PTR [esi+4] == '1' inc DWORD PTR [ebx+4*(SIZEOF DWORD)] inc DWORD PTR [edi] .ENDIF .IF (DWORD PTR [edi]) invoke MessageBox, 0, OFFSET Buff, 0, 0 .ENDIF
Black_mirror > Сколько же теперь у тебя флагов? Скажем так, с каждой новой версией программы количество флагов увеличивается, сейчас пока их 7 %)
А ещё лучше будет так: Код (Text): mov esi, OFFSET Buff mov edi, OFFSET Flag mov ebp, OFFSET Flag1 mov bl, '1' .IF BYTE PTR [esi] == bl inc DWORD PTR [ebp] inc DWORD PTR [edi] .ENDIF .IF BYTE PTR [esi+2] == bl inc DWORD PTR [ebp+2*(SIZEOF DWORD)] inc DWORD PTR [edi] .ENDIF .IF BYTE PTR [esi+3] == bl inc DWORD PTR [ebp+3*(SIZEOF DWORD)] inc DWORD PTR [edi] .ENDIF .IF BYTE PTR [esi+4] == bl inc DWORD PTR [ebp+4*(SIZEOF DWORD)] inc DWORD PTR [edi] .ENDIF .IF (DWORD PTR [edi]) invoke MessageBox, 0, OFFSET Buff, 0, 0 .ENDIF