Сдвиг влево для удаления символа

Тема в разделе "WASM.BEGINNERS", создана пользователем ego, 11 окт 2005.

  1. ego

    ego New Member

    Публикаций:
    0
    Регистрация:
    25 сен 2005
    Сообщения:
    7
    Адрес:
    Russia
    Робята подмогите как реализовать сдвиг влево для того чтобы удалить символ из цепочки символов. У меня TASM
     
  2. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    Грубо говоря можно так (удалить четверку):
    Код (Text):
    1. string      db      '123456789',0
    2. size        =            $-string
    3.  
    4.             mov     esi,string
    5.             mov     edi,string
    6.             mov     ecx,4-1
    7.             repnz   movsb
    8.             mov     ecx,size-4
    9.             inc     esi
    10.             repnz   movsb
     
  3. ego

    ego New Member

    Публикаций:
    0
    Регистрация:
    25 сен 2005
    Сообщения:
    7
    Адрес:
    Russia
    А если месторасположение четверки в строчке неизвестно?
     
  4. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Если неизвестно, то никто не мешает найти месторасположение четверки и вставить в код вместо 4 новую позицию
     
  5. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Можно и не искать её месторасположение, просто пропустить когда встретится:


    Код (Text):
    1.                 .data
    2.                     string      db      '123456789',0
    3.                 .code
    4.                     lea     ebx,string
    5.                 _loop1:
    6.                     cmp     byte ptr[ebx],'4'
    7.                     je      _loop2
    8.                     cmp     byte ptr[ebx],0
    9.                     je      _fin
    10.                     inc     ebx
    11.                     jmp     _loop1
    12.                 _loop2:
    13.                     inc     ebx
    14.                     mov     al,byte ptr[ebx]
    15.                     mov     byte ptr[ebx-1],al
    16.                     test    al,al
    17.                     jnz     _loop2
    18.                 _fin:
    19.                     PrintString string
     
  6. ego

    ego New Member

    Публикаций:
    0
    Регистрация:
    25 сен 2005
    Сообщения:
    7
    Адрес:
    Russia
    Извините, но у меня возник вопрос, а что означает 0 в следующей записи: string db '123456789',0. Большое спасибо
     
  7. bogrus

    bogrus Active Member

    Публикаций:
    0
    Регистрация:
    24 окт 2003
    Сообщения:
    1.338
    Адрес:
    ukraine
    Не обращай внимания или считай его тоже символом, я по привычке добавил ноль как признак окончания строки, в том коде он не нужен (его роль выполняет переменная size), у cresta наоборот вместо переменной используется ноль (обычно это выгоднее)
     
  8. ego

    ego New Member

    Публикаций:
    0
    Регистрация:
    25 сен 2005
    Сообщения:
    7
    Адрес:
    Russia
    А если строчка символов находится в буфере. Ведь из этого же буфера выводить исправленную строчку нельзя, а тогда нужно использовать movs как тогда правильно задавать cx (количество передаваемых байтов)
     
  9. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    ego

    Ты бы уточнил задачку:

    1) какие у тебя строки - с замыкающим нулем или а-ля ShortString Pascal или еще какие ?

    2) какой символ тебе нужно удалять - по заданному номеру (индексу) от начала строки или его еще нужно найти (например найти и удалить пробел или все пробелы в строке) ?

    3) нужно изменить саму исходную строку или создать ее измененную копию ?
     
  10. ego

    ego New Member

    Публикаций:
    0
    Регистрация:
    25 сен 2005
    Сообщения:
    7
    Адрес:
    Russia
    нужно найти все эти символы и удалить их и создать измененную копию строки
     
  11. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    Память под результат надо выделять? Если нет тогда примерно так:

    (esi - адрес исходной строки, edi - адрес результата, al - удаляемый символ



    для ascii-z строк:
    Код (Text):
    1.  
    2. mloop:
    3.     mov     ah, byte ptr[esi]
    4.     inc     esi
    5.     cmp     ah, al
    6.     je      skip
    7.     mov     byte ptr[edi], ah
    8.     inc     edi
    9. skip:
    10.     or      ah, ah
    11.     jne     mloop
    12.  


    для pascal-строк:
    Код (Text):
    1.  
    2.     xor     ecx, ecx
    3.     mov     cl, byte ptr[esi]
    4.     mov     ebx, ecx
    5.     inc     esi
    6.     push    edi
    7.     inc     edi
    8. mloop:
    9.     mov     ah, byte ptr[esi]
    10.     inc     esi
    11.     cmp     ah, al
    12.     je      skip
    13.     mov     byte ptr[edi], ah
    14.     inc     edi
    15.     loop    mloop
    16. skip:
    17.     dec     ebx
    18.     loop    mloop
    19.     pop     edi
    20.     mov     byte ptr[edi], bl
    21.  
     
  12. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Ustus

    Кстати к вопросу об оптимизации: без особой необходимости не следует смешивать в одной операции младший и старший 8-битовые регистры, т.к. это требует дополнительного внутреннего мопа на сдвиг старшего байта. Так что если регистров хватает лучше использовать младшие байты разных регистров
     
  13. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    Согласен, просто написать за пять минут проще, чем оптимизировать за час :) да и прога вроде не для Пентагона :))

    и loop лучше заменить на dec\je(для Intel'а по крайней мере, AMD по-моему пофиг)





    М-м-м... чего-то я не нахожу такой пакости... это для всех процов?
     
  14. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Ustus

    > "loop лучше заменить на dec\je"

    Правильно, только лучше не на dec, а на sub ecx,1 т.к. dec имеет ложную и совершенно ненужную зависимость по флагу CF от предыдущих операций, а времена экономии пары байтов медленно, но верно уходят в прошлое ;)



    > "AMD по-моему пофиг"

    Тебе пофиг, а AMD нет ;) Открываем AMD Optimization Guide и видим, что loop это VectorPath с латентностью 8 тиков 8((, а dec+je от силы 2



    > "это для всех процов?"

    Ес-но, т.к. регистра ah в природе не существует, впрочем как и al - в 32-разрядных процах есть только eax (хотя на самом деле и его нет, но это уже другой вопрос ;)))



    > "написать за пять минут проще, чем оптимизировать за час"

    Это точно, но к родному языку, впитанному с молоком матери, это не относится ;)) Я например для себя не задумываясь пишу sub ecx,1 вместо dec ecx, но когда нужно запостить чего на форум старательно исправляю чтобы не вызывать лишних дискусий у любителей экономить байты ;) А всякие там loop - это вообще ненормативная лексика и произносить такое даже язык не поворачивается, тем более писать ;))



    PS: надеюсь, ты на смайлики внимание обращаешь и не воспринимаешь мои заметки близко к сердцу :)))
     
  15. ego

    ego New Member

    Публикаций:
    0
    Регистрация:
    25 сен 2005
    Сообщения:
    7
    Адрес:
    Russia
    Thank you very much!!!!!!!!!!!!!!!!!!!!!!
     
  16. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    leo



    Согласен, но:



    Скорее экономлю текстовое пространство :)





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