Подскажите есть ошибка ? (если да то где)

Тема в разделе "WASM.BEGINNERS", создана пользователем mikityak, 18 сен 2008.

  1. mikityak

    mikityak Забанен

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    160
    [​IMG]WinMain.asm
    Код (Text):
    1. .486
    2. .model flat,stdcall
    3. option casemap :none
    4. ;/////////////////////////////////////////////////////////////////////////////
    5.     include \MASM32\INCLUDE\Windows.inc
    6.     include \MASM32\INCLUDE\User32.inc
    7.     include \MASM32\INCLUDE\Kernel32.inc
    8. ;/////////////////////////////////////////////////////////////////////////////
    9.     includeLib \MASM32\LIB\User32.lib
    10.     includeLib \MASM32\LIB\Kernel32.lib
    11. ;/////////////////////////////////////////////////////////////////////////////
    12. .const
    13. ;/////////////////////////////////////////////////////////////////////////////
    14. .data
    15.     lpCaption db "Caption",0
    16. ;/////////////////////////////////////////////////////////////////////////////
    17. .data?
    18. ;/////////////////////////////////////////////////////////////////////////////
    19. .code
    20.  
    21. _start:
    22. ;/////////////////////////////////////////////////////////////////////////////
    23.  
    24.     CALL    GetCommandLineA     ;Kernel32.dll
    25.  
    26.     CALL    _wincmdln       ;WinMain.asm
    27.  
    28.     PUSH    NULL            ;lpModuleName
    29.     CALL    GetModuleHandleA    ;Kernel32.dll
    30.  
    31.     PUSH    ESI             ;lpCmdLine
    32.     PUSH    EAX             ;hInstance
    33.     CALL    WinMain         ;WinMain.asm
    34.  
    35.     PUSH    NULL            ;uExitCode
    36.     CALL    ExitProcess         ;Kernel32.dll
    37.  
    38. ;/////////////////////////////////////////////////////////////////////////////
    39. _wincmdln Proc
    40.  
    41.     MOV     ESI,EAX
    42.     MOV     AL,BYTE PTR DS:[ESI]
    43.     CMP     AL,34           ;ASCII (") 22h
    44.     JNZ     _exit           ;переход, если флаг Z неактивен
    45.     INC     ESI             ;удаляем символ ASCII (") 22h
    46. _loop:
    47.     MOV     AL,BYTE PTR DS:[ESI]
    48.     INC     ESI             ;удаляем первый символ
    49.     CMP     AL,34           ;ASCII (") 22h
    50.     JE  _finish         ;переход, когда активен флаг Z
    51.     JMP     _loop           ;безусловный переход
    52. _finish:
    53.     INC     ESI             ;удаляем символ ASCII (") 22h
    54.     MOV     AL,BYTE PTR DS:[ESI]
    55.     CMP     AL,32           ;ASCII ( ) 20h
    56.     JE  _space          ;переход, когда активен флаг Z
    57.     JMP     _exit           ;безусловный переход
    58. _space:
    59.     INC     ESI             ;удаляем пробел
    60. _exit:
    61.     RET
    62.  
    63. _wincmdln Endp
    64. ;/////////////////////////////////////////////////////////////////////////////
    65. WinMain Proc hInstance :HINSTANCE,lpCmdLine :LPSTR
    66.  
    67.     PUSH    MB_OK           ;uType
    68.     PUSH    offset lpCaption    ;lpCaption
    69.     PUSH    lpCmdLine       ;lpText
    70.     PUSH    NULL            ;hWnd
    71.     CALL    MessageBox      ;User32.dll
    72.  
    73.     RET
    74.  
    75. WinMain Endp
    76. ;/////////////////////////////////////////////////////////////////////////////
    77. end _start
     
  2. mikityak

    mikityak Забанен

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    160
    Александр Ильин
    Ошибка в порядке заталкивания параметров в стек. Для соглашения stdcall параметры push-аются в обратном порядке (т.е. справа-налево, если читать определение ф-ции)...
    http://www.programmersheaven.com/2/Calling-conventions#stdcall

    [​IMG] А я ничего не понял, у меня только одно сомнения нужна ли проверять и потом удалять пробел.. можно сразу удалять без проверки..
     
  3. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.914
    _mikityak_
    Можешь словами сформулировать задачу? Удалить из строки символы пробела и двойной кавычки? Если да, тогда можно проще
    Код (Text):
    1. mov esi,eax
    2. push esi
    3. mov edi,eax; адрес CmdLine
    4. a0: lodsb
    5.     test al,al
    6.     jz _exit; встретили завершающий ноль, значит конец CmdLine
    7.     cmp al,' '
    8.     jz a0; нашли символ пробела
    9.     cmp al,'"'
    10.     jz a0; нашли двойную кавычку
    11.     stosb
    12.     jmp a0 ; переходим к следующему символу
    13. _exit: stosb; передаем в строку завершающий ноль
    14. pop esi
    Под виндой DS:[ESI] префикс ds: указывать не нужно, он и так на него установлен
    Код (Text):
    1. PUSH    MB_OK           ;uType
    2.     PUSH    offset lpCaption    ;lpCaption
    3.     PUSH    lpCmdLine<-- здесь должено быть lea ecx, lpCmdLine/push ecx
    4.     PUSH    NULL            ;hWnd
    5.     CALL    MessageBox
     
  4. mikityak

    mikityak Забанен

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    160
    [​IMG] та ладно так загружать.. подумаеш посмотрел "Олькой" на командную строку "Microsoft Visual C++ 6.0"

    А без префикса ds: еррор получился.. [​IMG]

    Код (Text):
    1. /////////////////////////////////////////////////////////////////////////////
    2. Microsoft (R) Windows (R) Resource Compiler Version 5.2.3690.0
    3. Copyright (C) Microsoft Corporation.  All rights reserved.
    4.  
    5. Using codepage 1251 as default
    6. Creating rsrc.RES
    7. RC: RCPP -CP 1251 -f D:\Masm32\Examples\WinMain\RCa02052 -g D:\Masm32\Examples\W
    8. inMain\RDa02052 -DRC_INVOKED -D_WIN32 -pc\:/ -E -I. -I .
    9.  
    10. rsrc.rc.
    11. Writing ICON:1, lang:0x409,     size 1128
    12. Writing ICON:2, lang:0x409,     size 3240
    13. Writing GROUP_ICON:100, lang:0x409,     size 34.
    14. Writing 24:1,   lang:0x409,     size 780
    15. /////////////////////////////////////////////////////////////////////////////
    16. Microsoft (R) Windows Resource To Object Converter Version 5.00.1736.1
    17. Copyright (C) Microsoft Corp. 1992-1997. All rights reserved.
    18.  
    19. /////////////////////////////////////////////////////////////////////////////
    20. Microsoft (R) Macro Assembler Version 6.14.8444
    21. Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.
    22.  
    23.  Assembling: WinMain.asm
    24. WinMain.asm(42) : error A2070: invalid instruction operands
    25. -----------------------------------------------------------------------------
    26. Error Macro Assembler
    27. Для продолжения нажмите любую клавишу . . .
    кароче под строкой _finish:
    удаляю полностю..
    Код (Text):
    1. INC     ESI             ;удаляем символ ASCII (") 22h
    типа ненужна ета строк.. а так аставляю как есть..

    А ет чо такое ???
     
  5. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    _mikityak_
    Mikl___ > "Можешь словами сформулировать задачу?"
    +1

    Mikl___
    PUSH lpCmdLine<-- здесь должено быть lea ecx, lpCmdLine/push ecx
    Заблуждаешься.
     
  6. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    _mikityak_
    А заюзать CommandLineToArgvW незя? Или masm32.lib (оно к тому-же с исходниками)?
     
  7. mikityak

    mikityak Забанен

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    160
    "Можешь словами сформулировать задачу?" нет задачи.. просто взял Microsoft Visual C++ 6.0 зделал пустой проект и захотелось Олькой посмотреть командную строку, да крива получилась.. но то што получилось хотел узнать какие имено ошыпки допустил.. CommandLineToArgvW - потому и ненадо.. [​IMG]
     
  8. mikityak

    mikityak Забанен

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    160
    знаю што строка под _finish: ненужна ))
     
  9. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    _mikityak_
    хотел узнать какие имено ошыпки допустил
    Судя по твоему коду из #1 и заголовку темы, ты просишь проверить _wincmdln. Предполагаю, что ты хотел, чтобы она возвращала адрес того места командной строки, с которого начинаются параметры. Я прав?
     
  10. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    _mikityak_
    32 == 20h == ' '
    48 == 30h == '0'
    итд

    попрубуйте для начала просто вывести всю командную строку без преобразований
    для потома, при операциях со строками никогда не забывайте проверять на конец строки
    вы выгоняете всю комстроку, а затем выкидываете конечный 0
     
  11. mikityak

    mikityak Забанен

    Публикаций:
    0
    Регистрация:
    5 авг 2007
    Сообщения:
    160
    q_q ну ДА )) (и не ждал я вариантов как можно достать ком-строку.. я знаю што мой неочень.. просто скажыте если там чото нетак как для такова)

    п.с
    спишу потому по русски карлякаю как магу [​IMG]
     
  12. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    _mikityak_
    просто скажыте если там чото нетак
    Есть.

    Например;
    1) если имя исполняемого модуля не заключено в двойные кавычки, то сработает первый условный переход - JNZ _exit и на выходе из _wincmdln esi будет указывать не на параметры, а на имя исполняемого модуля;
    2) в цикле между _loop и _finish перед проверкой на завершающую двойную кавычку уже есть INC ESI, т.е. двойная кавычка пропущена, получается, что INC ESI после метки _finish пропускает разделитель между именем исполняемого модуля и первым параметром, а если параметров нет, то следующую команду MOV AL,BYTE PTR DS:[ESI] можно расценивать как попытку прочитать за пределами строки;
    3) между именем исполняемого модуля и первым параметром может быть несколько пробелов;
    4) в качестве разделителя между именем исполняемого модуля и параметрами может быть использован знак(ки) табуляции.