Как изменить байт в строке?

Тема в разделе "WASM.BEGINNERS", создана пользователем xlinuks, 11 авг 2006.

  1. xlinuks

    xlinuks New Member

    Публикаций:
    0
    Регистрация:
    25 май 2006
    Сообщения:
    181
    Привет, в этом коде я пытаюсь заменить вручную отдельный байт в строке на другой байт, что, по идее изменит содержимое строки, но почемуто программа завершается аварийно, подскажите пожалуйста как исправить так чтобы работало

    Код (Text):
    1. .386
    2. .model flat,stdcall
    3. option casemap:none
    4.  
    5. include \masm32\include\windows.inc
    6. include \masm32\include\kernel32.inc
    7. include \masm32\include\user32.inc
    8.  
    9. includelib \masm32\lib\kernel32.lib
    10. includelib \masm32\lib\user32.lib
    11.  
    12. .DATA
    13. sMessage db "Some string to be changed.", 0
    14. sMesTitle db "Title", 0
    15. dwMessageAddr DWORD offset sMesTitle
    16.  
    17. .CODE
    18. start:
    19. mov dwMessageAddr, offset sMessage
    20. mov [dwMessageAddr+2], 97 ; ЗДЕСЬ (по идее) меняю второй байт(букву) в строке на байт 97 (a)
    21. invoke MessageBox, NULL, dwMessageAddr, addr sMesTitle, MB_OK
    22.  
    23. invoke ExitProcess, NULL
    24.  
    25. end start
     
  2. Developer_PROFX

    Developer_PROFX New Member

    Публикаций:
    0
    Регистрация:
    22 мар 2004
    Сообщения:
    16
    Так работает:
    Код (Text):
    1. .386
    2. .model flat,stdcall
    3. option casemap:none
    4.  
    5. include \masm32\include\windows.inc
    6. include \masm32\include\kernel32.inc
    7. include \masm32\include\user32.inc
    8.  
    9. includelib \masm32\lib\kernel32.lib
    10. includelib \masm32\lib\user32.lib
    11.  
    12. .DATA
    13. sMessage db "Some string to be changed.", 0
    14. sMesTitle db "Title", 0
    15.  
    16.  
    17. .CODE
    18. start:
    19. mov esi,offset sMessage
    20. mov al,97
    21. mov [esi+2], al ; ЗДЕСЬ (по идее) меняю второй байт(букву) в строке на байт 97 (a)
    22. invoke MessageBox, NULL, addr sMessage,addr sMesTitle, MB_OK
    23.  
    24. invoke ExitProcess, NULL
    25. end start
     
  3. xlinuks

    xlinuks New Member

    Публикаций:
    0
    Регистрация:
    25 май 2006
    Сообщения:
    181
    Значит, работать нужно через регистры
    Спасибо!!
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    xlinuks
    Необязательно, просто нужно понимать что к чему ;)
    mov [dwMessageAddr+2], 97 означает запись по адресу offset dwMessageAdr+2, т.е. в третий байт переменной dwMessageAddr, а не строки sMessage
    Поэтому правильно было бы так
    mov byte ptr [sMessage+1], 97 ;!!! +1 - меняем второй байт, +2 - третий и т.д.
     
  5. xlinuks

    xlinuks New Member

    Публикаций:
    0
    Регистрация:
    25 май 2006
    Сообщения:
    181
    OK leo, твой код работает тоже, а главнее он еще лаконичнее! Это клево. Но теперь когда я решил создать свою процедуру которая заменяет байт в строке (не для оптимизации чегото, а в учебных целях) то происходит следующее, когда я запускаю экзешку из консоли она работает без проблем, но когда при помощи двойного щелчка на экзешке то выдается *Access violation error*, почему так происходит? Ведь и так и так это win32 программа, разница только в том откуда я ее запускаю, а она так странно себя ведет.. Если не трудно взгляните пожалуйста на исходник:
    Код (Text):
    1. .386
    2. .model flat,stdcall
    3. option casemap:none
    4.  
    5. include \masm32\include\windows.inc
    6. include \masm32\include\kernel32.inc
    7. include \masm32\include\user32.inc
    8.  
    9. includelib \masm32\lib\kernel32.lib
    10. includelib \masm32\lib\user32.lib
    11.  
    12. str_replace PROTO :dword, :dword, :byte
    13.  
    14. .DATA
    15. sMessage db "A sample string", 0
    16. sMesTitle db "Title", 0
    17.  
    18. .CODE
    19. start:
    20. invoke str_replace, offset sMessage, dword ptr 10, byte ptr 65
    21. ;mov esi, offset sMessage
    22. ;mov [esi+1], byte ptr 65
    23. invoke MessageBox, NULL, offset sMessage, addr sMesTitle, MB_OK
    24.  
    25. invoke ExitProcess, NULL
    26.  
    27. ;==========================================================================
    28. str_replace proc dwStringAddress :dword, dwCharOffset :dword, bChar :byte
    29.     mov edi, dwStringAddress
    30.     add edi, dwCharOffset
    31.     add esi, edi
    32.     mov al, bChar
    33.     mov [esi], al ;ЗДЕСЬ в винде глючит и в дебаггере пишет *access violation*
    34.     ret
    35. str_replace endp
    36. ;===========================================================================
    37.  
    38.  
    39. end start
     
  6. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    ну дык изначально у тебя esi ваще не инициализируется
    зачам это делать? просто потом обращайся [edi]
    или вообще так :
     
  7. xlinuks

    xlinuks New Member

    Публикаций:
    0
    Регистрация:
    25 май 2006
    Сообщения:
    181
    Да, спасибо, я как раз тоже заметил эту ошибку.
    Я извиняюсь за настойчивость, но как засунуть теперь эту процедуру в структуру?
    что-то вроде
    Код (Text):
    1. .DATA
    2. strucStr struc
    3. ;==========================================================================
    4.     str_replace proc dwStringAddress :dword, dwCharOffset :dword, bChar :byte
    5.         mov edi, dwStringAddress
    6.         add edi, dwCharOffset
    7.         mov esi, edi ;здес было add вместо mov
    8.         mov al, bChar
    9.         mov [esi], al ;теперь не глючит
    10.         ret
    11.     str_replace endp
    12. ;===========================================================================
    13. strucStr ends
    14.  
    15. s strucStr <>
    16. .CODE
    17. start:
    18. invoke s.str_replace, offset sMessage, dword ptr 10, byte ptr 65
    не работает, масм 6.14 выдает ошибки и я никак не могу догнать почему. А может в структуре нельзя задавать процедуры?
    Может есть доки которые описывают эти случаи, я искал и на форуме и в интернете но не нашел ничего про процедуры (с параметрами желательно) внутри структур. Может плохо искал.
     
  8. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    ого куда тебя мечта завела =) это не сишные классы, это просто структура. ваще-то так нельзя, если хочеш, можно сделать что-бы в структуре был членом адрес процедуры, потом вызывать его можно
    но в этом случае процедуру нада написать отдельно а потом помещать её адрес в переменную структуры,но как в таком случае использавть invoke незнаю, может кто подскажет (только через push&call)
    Кстати намедни чатал сабклассинг Iczelion'a там когда получаеш адрес процедуры сабклашенного окна её рекомендуется вызывать через CallWindowProc, я же вызывал её через push&call и в сразу работало, но в эксерементах с другими окнами выдавало memory cannot be read, интересно почему так происходит?