Поиск строки в памяти

Тема в разделе "WASM.BEGINNERS", создана пользователем dessaber, 23 дек 2011.

  1. dessaber

    dessaber New Member

    Публикаций:
    0
    Регистрация:
    20 ноя 2011
    Сообщения:
    26
    Здравствуйте, дорогие люди. Есть задание - найти строку (ну просто строка, она не вводится, всего лишь определяется в самой программе). Есть некий (хех) код:
    Код (Text):
    1. .model small
    2. .stack 100h
    3. .data
    4. x db 'hola'
    5. .code
    6. start:
    7. mov ax,@data
    8. mov ds,ax
    9. xor ax,ax
    10.  
    11. mov BX, 0                        ;с чего начинаем
    12. mov ES,BX
    13.  
    14. searchin:
    15. mov Dx, BX            ;помещаем в DI адрес, хранящийся в ES:BX
    16. push BX                          ;помещаем  BX в стек
    17. lea si, x                           ;заносим эффективный адрес (смещение) Х в SI
    18. lodsb                               ;извлекаем элемент из SI в AL, меняем значение SI на величину, равную длине элемента
    19. cmp Dx, ax                       ;сравниваем
    20. jne enhancin                             ;если не равно, переход на M1
    21.  
    22. inc si                              ;если равно, то увеличиваем SI (переходим на следующий элемент)
    23. inc bx                            ;увеличиваем BX
    24. mov Dx,BX            
    25. lodsb
    26. cmp dx,ax
    27. jne enhancin
    28.  
    29. inc si
    30. inc bx
    31. mov Dx, BX
    32. lodsb
    33. cmp dx,ax
    34. jne enhancin
    35.  
    36. inc si
    37. inc bx
    38. mov Dx, BX
    39. lodsb
    40. cmp dx,ax
    41. jne enhancin
    42.  
    43. enhancin:
    44. pop BX                      ;достаем из стека значение и записываем в BX
    45. inc BX                       ;наращиваем BX
    46. cmp BX, 0ffffh            ;полон ли BX?
    47. jne searchin                     ;если нет, то переход на asd1
    48.  
    49. push BX                    
    50. mov BX, ES               ;записываем содержимое ES в BS
    51. inc BX              
    52. cmp BX, 0ffffh            
    53. mov ES, BX
    54. pop BX
    55. jne searchin
    56.  
    57. mov ax,4c00h
    58. int 21h
    59. end start
    насколько я понимаю, код не совсем верен. Можно даже сказать, совсем неверен, вместо поиска, собственно адреса, есть просто инкрементирование содержимого регистров BX & ES. В связи с этим у меня есть несколько вопросов:
    1) вот к примеру нашлось у меня совпадение (cmp Dx, ax). Это значит что адрес первой буквы строки будет равен содержимому DX (или АХ). Когда будет второе совпадение, то что нужно сделать? Чтобы получить на выходе адрес строки нужно последовательно складывать, то что мы получаем при совпадениях? Или мы должны записывать это в новый разряды? Просто циферки друг за другом?
    2) касательно вывода (нужно его приделать будет). Адрес целиком сразу не получится вывести, так ведь? Т.е. нужно выводить посимвольно? Каким образом нужно будет переходить к последующим символам адреса? Куда-то скидывать после вывода символ из начала строки, затем выводить следующий? Каким прерыванием?
     
  2. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Вот и мы отвечаем - ХЕХ. Полная деградация. Все твои вопросы описаны в учебниках. Э-ле-мен-тар-щи-на. Поздно батенька - Новый год приближается.
     
  3. shore

    shore New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2011
    Сообщения:
    29
    Процедура поиска строки в блоке памяти с использованием бинарной маски
    Код (Text):
    1. proc scanmem SRCdata:dword, SRCsize:dword, PTRdata:dword,\
    2.              PTRsize:dword, MSKdata:dword
    3.         push    esi edi ebx ecx edx
    4.         ; Длина паттерна больше длины данных?
    5.         mov     eax,[PTRsize]
    6.         cmp     eax,[SRCsize]
    7.         ; Да, возврат -1
    8.         ja      .scanmem_not_found
    9.         mov     esi,[SRCdata]
    10.         mov     edi,[PTRdata]
    11.         mov     edx,[MSKdata]
    12.         mov     ebx,esi
    13.         add     ebx,[SRCsize]
    14.         sub     ebx,[PTRsize]
    15. .scanmem_loop:
    16.         xor     ecx,ecx
    17. .scanmem_test_char:
    18.         or      edx,edx
    19.         jz      .scanmem_no_mask
    20.         cmp     byte [edx+ecx],0
    21.         jz      .scanmem_char_equal
    22. .scanmem_no_mask:
    23.         mov     al,[esi+ecx]
    24.         cmp     al,[edi+ecx]
    25.         jne     .scanmem_next_pattern
    26. .scanmem_char_equal:
    27.         inc     ecx
    28.         cmp     ecx,[PTRsize]
    29.         jb      .scanmem_test_char
    30.         jmp     .scanmem_found
    31. .scanmem_next_pattern:
    32.         inc     esi
    33.         cmp     esi,ebx
    34.         jbe     .scanmem_loop
    35. .scanmem_not_found:
    36.         ; Строка не найдена
    37.         mov     eax,-1
    38.         jmp     .scanmem_ret
    39. .scanmem_found:
    40.         ; Строка найдена
    41.         mov     eax,esi
    42. .scanmem_ret:
    43.         pop    edx ecx ebx edi esi
    44.         ret
    45. endp
     
  4. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    shore
    Можно поподробнее про бинарную маску? Что это за зверь такой?
     
  5. shore

    shore New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2011
    Сообщения:
    29
    K10
    Бинарная(битовая) маска является значением (которое может храниться в переменной), которое позволяет изолировать определенный набор битов целого типа.
    Обычно в маске будет бит вы заинтересованы в значение 1, а все остальные биты установлены в 0.
    Маска затем позволяет изолировать значение бита, очистить все биты, установить все биты или установить новое значение битов.
    Маски (особенно мульти-битные) часто имеют сдвиг значения, которое необходимо чтобы младший масках бит переместился в младший бит в типе.
    Например, если использовать 16-битный короткий тип данных, чтобы замаскировать биты 3, 4 и 5 (LSB имеет номер 0).
    Маска и сдвиг будет выглядеть примерно так:

    # определяем MASK 0x0038
    # определяем SHIFT 3
    Если у меня есть переменная, вар, который содержит данные,и соответствующая маска, то я могу выделить биты, так:
    vаr & MASK
    Выделить все остальные биты, так
    уаr & ~ MASK
    Очистить бит, так
    vаr & = ~ MASK;
    Удалить все другие биты, так
    vаr & = MASK;
    Установить все биты, так
    vаr | = MASK;
    Установить все остальные биты, так
    vаr | = ~ MASK;
    Извлечь десятичное значение бита, так
    (переменная & MASK)>> SHIFT
    Назначить новое значение бита, так
    vаr & = ~ MASK;
    vаr | = (NewValue <<SHIFT) и маски;

    в данном случае, для поиска задается бинарная(битовая) маска, каждый элемент которой может принимать значения 0, 1 или *.
    0 — в этом месте в найденном результате должен быть бит 0.
    1 — в этом месте в найденном результате должна быть бит 1.
    * — в этом месте в найденном результате может быть любой бит.

    http://www.inetdaemon.com/tutorials/basic_concepts/number_systems/binary/masks.shtml
     
  6. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    dessaber

    Зачем сразу брать ассемблер, если ты даже алгоритм придумать не можешь? А алгоритм-то элементарный. Реши для начала задачу на Си, на массивах. Как поймешь алгоритм - переписывай на ассемблере.
     
  7. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    shore
    Спасибо.