Опять какая-то ерунда с локальными параметрами функции

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

  1. zukalo

    zukalo New Member

    Публикаций:
    0
    Регистрация:
    22 окт 2008
    Сообщения:
    20
    Есть такой кусок кода:
    proc dirlst uses eax ebx ecx edx edi esi, ptDir:lol: WORD
    local FindFileData:WIN32_FIND_DATA
    invoke FindFirstFile, [ptDir], dword [FindFileData]

    По идее правильно, ведь FindFileData указатель на указатель на структуру,
    тогда [FindFileData] и есть указатель на структуру, который я собственно и передаю в функцию. Прога собирается только так вроде (invoke FindFirstFile, [ptDir], dword [FindFileData]). Но выскакивает эксепшн в связи с тем, что FindFirstFile пытается писать по нулевому адресу. Как я понял, берёт он его из первых 4 байт от WIN32_FIND_DATA.
    Так как же правильно? Уже полдня с этим мучаюсь. Зараннее спасибо.
     
  2. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    по моему правильно будет так:
    Код (Text):
    1.      lea eax, [FindFileData]
    2.      invoke FindFirstFile, [ptDir], eax
    Так как:
    Код (Text):
    1.     local FindFileData:WIN32_FIND_DATA
    выделяет в стеке данную структуру, и обращение к [FindFileData] производит к обращению непосредственно к содержимому этой структуры.
     
  3. zukalo

    zukalo New Member

    Публикаций:
    0
    Регистрация:
    22 окт 2008
    Сообщения:
    20
    Действительно, работает, но теперь со структурой возникла другая проблема.
    Код (Text):
    1. lea eax, [FindFileData]
    2. mov [ffd], eax
    3.  
    4. invoke FindFirstFile, [ptDir], [ffd]
    5. ...
    6. invoke lstrcmp, dword [ffd + WIN32_FIND_DATA.cFileName], "."
    dword [ffd + WIN32_FIND_DATA.cFileName] выдаёт адрес FFFFFFFF.
    dword [ffd.cFileName] также не работает :dntknw:

    Получилось так:
    Код (Text):
    1.                 mov eax, [ffd]
    2.                 add eax, WIN32_FIND_DATA.cFileName
    3.                 invoke lstrcmp, eax, "."
    А проще можно как-нибудь?
     
  4. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    есчо раз повторяю - адреса локальных переменных (или их смещение) загружается с помощью инструкции lea. А вы опять заталкиваете в стек не адрес поля ffd, а значение содержащиеся в стеке (т. к. структура была выделена в стеке, и единственный способ получить адрес смещения - это инструкция вычисления эффективного адреса, т. е. lea).

    Юзайте так:
    Код (Text):
    1. lea eax, [ffd.cFileName]
    2. invoke lstrcmp, eax, "."
    или так:
    Код (Text):
    1. lea eax, [ffd + WIN32_FIND_DATA.cFileName]
    2. invoke lstrcmp, eax, "."
    и покурите насчет инструкции lea.
     
  5. zukalo

    zukalo New Member

    Публикаций:
    0
    Регистрация:
    22 окт 2008
    Сообщения:
    20
    Большое спасибо за потраченное время.

    С lea и локальными переменными более-менее разобрался, но дело в том, что
    lea eax, [ffd + WIN32_FIND_DATA.cFileName]
    заносит в eax неправильный адрес, это видно даже в отладчике!
     
  6. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    zukalo
    Всё он правильно заносит.
    ffd - адрес, по которому хранится адрес структуры.
    ffd + WIN32_FIND_DATA.cFileName - адрес, по которому хранятся данные, смещённые относительно ffd (по сути неизвестно, что).
    [ffd + WIN32_FIND_DATA.cFileName] - сами эти данные (неизвестно, что).
    [ffd]+ WIN32_FIND_DATA.cFileName - указатель на поле структуры cFileName.
    А вот теперь думайте, как это оформить в виде кода. А ещё лучше думайте до того, как запостить вопрос.
    P.S.
    Arthur
    В посте 4 Вы не правы. Ваш хрустальный шар Вам не показал всю картину о том, что есть ffd.
     
  7. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    l_inc
    Где именно я не прав?
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Arthur
    Вообще-то я уже указал в предыдущем посте, что есть ffd. Содержит не структуру WIN32_FIND_DATA, а указатель на неё. Соответственно ffd в фасме - указатель на указатель на структуру.
    И отсюда вполне очевидно, что ни один из предложенных Вами вариантов:
    ни lea eax, [ffd + WIN32_FIND_DATA.cFileName],
    ни lea eax, [ffd.cFileName]
    неверен.

    Зачем автору взбрело в голову выделять отдельную переменную под адрес структуры, не знаю, но это следует из его кода:
    lea eax, [FindFileData]
    mov [ffd], eax
    P.S. Ах да... чуть не забыл. Собственно ответ на вопрос
    Везде. :) (в четвёртом посте)
     
  9. Arthur

    Arthur New Member

    Публикаций:
    0
    Регистрация:
    27 янв 2007
    Сообщения:
    494
    l_inc
    ага, невнимательность :) Действительно, ffd это судя по всему - дворд (а я посчитал, что автор просто сократил название переменной FindFileData, и не заметил шаманства с этой переменной) :)

    Поэтому вот верное решение:
    Код (Text):
    1. lea eax, [FindFileData.cFileName]
    2. invoke lstrcmp, eax, "."
    Или так:
    Код (Text):
    1. lea eax, [FindFileData + WIN32_FIND_DATA.cFileName]
    2. invoke lstrcmp, eax, "."
     
  10. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    очень громоздко. если это попытка отбросить "имя" текущей директории - тогда можно сделать проще:
    Код (Text):
    1. cmp word [FindFileData + WIN32_FIND_DATA.cFileName],"."
     
  11. zet

    zet New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2007
    Сообщения:
    121
    Необходимо использовать подключаемый файл win32wx.inc или win32ax.inc

    Код (Text):
    1. proc dirlst uses eax ebx ecx edx edi esi, ptDir:DWORD
    2. locals
    3.   FindFileData WIN32_FIND_DATA ?
    4. endl
    5.      invoke FindFirstFile, [ptDir], addr FindFileData
     
  12. zukalo

    zukalo New Member

    Публикаций:
    0
    Регистрация:
    22 окт 2008
    Сообщения:
    20
    Ну с отбрасыванием ".." такое уже не проделаешь, поэтому я использовал универсальный метод.