проблема с переменными и регистрами.

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

  1. klakens

    klakens New Member

    Публикаций:
    0
    Регистрация:
    22 сен 2005
    Сообщения:
    4
    Адрес:
    Russia
    Привет. Это моя первая прога на асме. SendMail-заглушка на локальный сервер. Консольный ввод переправляет в файл.

    Две проблемы, которые, я не могу решить:

    1. Файл создается не больше 4096 байт. Надо без ограничений на размер.

    2. В начало файла вставляется 4 00 (символ 00h четыре штуки :). Проблема _НЕ_ в сервере, а в коде проги.



    Пожалуйста, помогите.



    Вот код программы:


    Код (Text):
    1.  
    2. ;========
    3. ;SendMail
    4. ;========
    5.  
    6. .386
    7. .model flat, stdcall
    8. option casemap:none
    9. include \masm32\include\windows.inc
    10. include \masm32\m32lib\masm32.inc
    11. include \masm32\include\kernel32.inc
    12. include \masm32\macros\Macros.asm
    13. includelib \masm32\m32lib\masm32.lib
    14. includelib \masm32\lib\kernel32.lib
    15.  
    16. .data
    17.     GetDateTime SYSTEMTIME <>
    18.     timeformat  DB "HH-mm-ss", 0
    19.     dateformat  DB "yyyy-MM-dd_", 0
    20.     time        DB 16 dup (0)
    21.     date        DB 64 dup (0)
    22.     bRead       DD 0
    23.  
    24. .data?
    25.     hInput      HANDLE ?
    26.     hFile       HANDLE ?
    27.     InputBuffer DW 8192 dup(?)
    28.  
    29. .code
    30. start:
    31.  
    32.     invoke GetStdHandle, STD_INPUT_HANDLE
    33.     mov hInput, eax
    34.     invoke SetConsoleMode, hInput, ENABLE_LINE_INPUT or ENABLE_ECHO_INPUT or ENABLE_PROCESSED_INPUT
    35.     invoke ReadFile, hInput, ADDR InputBuffer, LENGTHOF InputBuffer, ADDR bRead, NULL
    36.     mov ebx, bRead
    37.     mov eax, 0
    38.  
    39.     invoke GetLocalTime, ADDR GetDateTime
    40.     invoke GetTimeFormat, LOCALE_USER_DEFAULT, NULL, ADDR GetDateTime, ADDR timeformat, ADDR time, SIZEOF time
    41.     invoke GetDateFormat, LOCALE_USER_DEFAULT, NULL, ADDR GetDateTime, ADDR dateformat, ADDR date, SIZEOF date
    42.  
    43.     invoke szCatStr, ADDR date, ADDR time
    44.     invoke szCatStr, ADDR date, SADD (".eml")
    45.  
    46.     invoke CreateFile, ADDR date, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
    47.     mov hFile, eax
    48.     invoke WriteFile, hFile, ADDR InputBuffer, ebx, ADDR InputBuffer, NULL
    49.     invoke CloseHandle, hFile
    50.  
    51.     invoke ExitProcess, NULL
    52.  
    53. end start
    54.  




    Объясните пжл, почему это происходит ;)
     
  2. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    Код (Text):
    1.  
    2. invoke WriteFile, hFile, ADDR InputBuffer, ebx, ADDR InputBuffer, NULL
    3.  


    надо:

    invoke WriteFile, hFile, ADDR InputBuffer, bRead, ADDR bWrite, NULL



    PS: регистры ebx, esi, edi лучше не менять при работе с WinAPI, а то такие глюки могут пойти, что не поймешь :)
     
  3. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    yureckor

    Да нет, просто нужно понимать, что делаешь.



    В Win API callback-функциях эти регистры нужно сохранять и восстанавливать, если изменяешь.
     
  4. yureckor

    yureckor New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2004
    Сообщения:
    494
    Адрес:
    Russia
    IceStudent

    ага, до выхода следующей версии винды.

    лучше стараться следовать спецификации, иначе о долгой жизни проги можно забыть.



    А вообще несоответствий между версиями дохрена.

    Например (не очень давно нашел, когда писАл программку, убивающую определенный процесс) CreateToolhelp32Snapshot/Process32First/Process32Next на XP в PROCESSENTRY32.szExeFile выдает имя экзешника, а на 98 полный путь к нему и имя.
     
  5. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    yureckor

    Ну вот. Ты ставишь под сомнение основу основ Win32 API? :)





    Вот-вот, а что в спецификации? Читаем соглашение STDCALL. Если мы вызываем stdcall-функцию, то она гарантирует, что сохранит в первоначальном состоянии ebx/esi/edi и некоторые флаги из EFLAGS (DF например), если вызывают нашу stdcall-функцию (при callback например), то мы должны гарантировать то же.
     
  6. klakens

    klakens New Member

    Публикаций:
    0
    Регистрация:
    22 сен 2005
    Сообщения:
    4
    Адрес:
    Russia
    ОК. yureckor Пасиб, кое в чем помог.



    проблема №2 решена.



    Код выглядит так
    Код (Text):
    1.  
    2. .386
    3. .model flat, stdcall
    4. option casemap :none
    5.  
    6. include \masm32\include\windows.inc
    7.  
    8. include \masm32\include\kernel32.inc
    9. include \masm32\include\masm32.inc
    10.  
    11. includelib \masm32\lib\kernel32.lib
    12. includelib \masm32\lib\masm32.lib
    13.  
    14. include \masm32\macros\Macros.asm
    15.  
    16. Main    PROTO
    17.  
    18. .data
    19.     GetDateTime SYSTEMTIME <>
    20.     timeformat  DB "HH-mm-ss", 0
    21.     dateformat  DB yyyy-MM-dd_", 0
    22.     time        DB 16 dup (0)
    23.     date        DB 32 dup (0)
    24.  
    25. .code
    26.  
    27. start:
    28.     invoke Main
    29.     invoke ExitProcess, NULL
    30.  
    31. Main proc
    32.  
    33.     LOCAL InputBuffer[4096] :BYTE
    34.     LOCAL hInput        :DWORD
    35.     LOCAL bRead     :DWORD
    36.  
    37.     LOCAL hFile     :DWORD
    38.     LOCAL bWrite        :DWORD
    39.  
    40.     invoke GetLocalTime, ADDR GetDateTime
    41.     invoke GetTimeFormat, LOCALE_USER_DEFAULT, NULL, ADDR GetDateTime, ADDR timeformat, ADDR time, SIZEOF time
    42.     invoke GetDateFormat, LOCALE_USER_DEFAULT, NULL, ADDR GetDateTime, ADDR dateformat, ADDR date, SIZEOF date
    43.     invoke szCatStr, ADDR date, ADDR time
    44.     invoke szCatStr, ADDR date, SADD (".eml")
    45.  
    46.     invoke GetStdHandle, STD_INPUT_HANDLE
    47.     mov hInput, eax
    48.     invoke SetConsoleMode, hInput,ENABLE_LINE_INPUT or ENABLE_ECHO_INPUT or ENABLE_PROCESSED_INPUT
    49.     invoke ReadFile, hInput, ADDR InputBuffer, LENGTHOF InputBuffer, ADDR bRead, NULL
    50.     mov eax, bRead
    51.     invoke  CloseHandle, hInput
    52.  
    53.     invoke CreateFile, ADDR date, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
    54.     mov hFile, eax
    55.  
    56.     invoke WriteFile, hFile, ADDR InputBuffer, bRead, ADDR bWrite, NULL
    57.     mov eax, bWrite
    58.     invoke  CloseHandle, hFile
    59.  
    60.     ret
    61.  
    62. Main endp
    63.  
    64. end start
    65.  




    Ограничение на 4096 байт осталось. Думаю надо пользовать SetEndOfFile. Нет ли у кого-нибудь толкового примера?



    PS. Вот это:
    Код (Text):
    1.  
    2. LOCAL InputBuffer[4096] :BYTE


    тут не причем. (Ну то есть... понятно, да?)
     
  7. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    klakens



    Хех. Это может и не при чём, а вот это причём:





    Ты читаешь из Input максимум 4096 байт. Нужно организовать цикл и в нём читать весь буфер.



    Кстати, не знаю, как насчёт STD_INPUT_HANDLE, но при чтении из выхода другой проги очень просто зависнуть, ожидая эти пресловутые 4096 байт (если она отдала меньше). Нужно узнавать размер данных, подлежащих прочтению, через PeekConsoleInput.
     
  8. klakens

    klakens New Member

    Публикаций:
    0
    Регистрация:
    22 сен 2005
    Сообщения:
    4
    Адрес:
    Russia
    Не-не именно ни причем: сначала было 65536, потом 16384, теперь 4096.



    А PeekConsoleInput щас поковыряю :) Пасиб.
     
  9. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    klakens

    Так, товарищ. Ты почитай внимательно описание функции ReadFile и её параметров.
     
  10. klakens

    klakens New Member

    Публикаций:
    0
    Регистрация:
    22 сен 2005
    Сообщения:
    4
    Адрес:
    Russia
    Ага, я уже почитал :)))

    Теперь размер письма неограничен (наверное)

    Отправил себе письмецо ~600 Мб :)))

    peekconsoleinput здесь не нужен.

    readconsole и readconsoleinput тоже.

    Всем пасиб :)))



    ЗЫ. Надо купить себе хорошую книгу по асму.

    А этим пользовался.
     
  11. mix_mix

    mix_mix Михаил

    Публикаций:
    0
    Регистрация:
    8 окт 2005
    Сообщения:
    277
    Адрес:
    Токио
    invoke WriteFile, hFile, ADDR InputBuffer, bRead, ADDR bWrite, NULL

    Сделай так:

    invoke WriteFile, hFile, ADDR InputBuffer, SIZEOF InputBuffer, ADDR bWrite, NULL

    То есть забей на bRead и bWrite, а InputBuffer помести в секцию data? :

    .data?

    InputBuffer db ого-го dup(?)