Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Asm для начинающих > masm32, invoke


Автор: race1 24.11.2008, 15:12
Привет!

Пытаюсь вызвать ф-ю GetTextExtentPoint32 и получаю ошибку.

Код

GameTimer proc
    local dc: HDC
    local textWidth: POINT
    local sptr: DWORD
...
    mov sptr, ptr$(s)
...
    mov s, 0
    mov sptr, cat$(sptr, "Игрок 2, очки: ", ustr$(FDude2Count))
...
    ; варианты, описанные ниже
...
    invoke TextOut, dc, 10, 10, "kva", 3


Вариант номер один:

Код

    invoke GetTextExtentPoint32, dc, sptr, len(sptr), ptr$(textWidth)


Компилируется нормально, но видимо происходит Access Violation, в итоге последующий invoke ничего не рисует (OllyDbg пишет в статусной строке AV когда F8 строку invoke GetTextExtentPoint32 ...

Вариант номер два:

Код

    invoke GetTextExtentPoint32, dc, sptr, len(sptr), addr textWidth


Получаю ошибку при компиляции: error A2133: register value overwritten by INVOKE

Ну в общем много вариантов перепробовал, потому что не уверен как правильно smile Хотя например 

Код
invoke GetClientRect, hWnd, addr clientRect


работает как надо. Структуры SIZE и POINT одинаковы, и там и там два LONG.

Помогите пожалуйста, что здесь не так.

Автор: Mikl_ 25.11.2008, 07:05
race1, второй аргумент GetTextExtentPoint32 адрес строки, третий аргумент количество символов в строке (видимо ссылаться нужно на строку s) тоже самое будет с TextOut, dc, 10, 10, "kva", 3 -- ассемблер это не С, которая расположит "kva" в локальном буфере, а потом удалит его, здесь всё делается ручками  smile 
IMHO нужно так invoke GetTextExtentPoint32, dc, offset s, length(s), addr textWidth

Автор: dumb 25.11.2008, 12:27
необходимо избегать применения макросов в параметрах invoke, так как они(макросы) используют для возврата значения регистр eax, и в результате получается "борьба" за этот регистр.

и если при использовании ADDR(встроенный макрос) компилятор отслеживает "незаконные" изменения eax и ругается(error A2133), то в случае ptr$ все происходит с "тихой сапой":

например в твоем случае, вследствие выноса вызовов функций "наверх", получается:
Код

push        sptr
call        szLen
lea         eax,textWidth ; ops. результат len перетерт адресом textWidth
mov         word ptr [eax],0
push        eax
push        eax
push        sptr
push        dc
call        GetTextExtentPoint32

как результат: GetTextExtentPoint32 пытается прочитать слишком много(например 12FFF0) из sptr - AV.

Автор: race1 25.11.2008, 20:39
Цитата(dumb @  25.11.2008,  17:27 Найти цитируемый пост)
необходимо избегать применения макросов в параметрах invoke, так как они(макросы) используют для возврата значения регистр eax, и в результате получается "борьба" за этот регистр.


О, да! То что надо! smile Переделал так:

Код

mov tmpDWORD, len(sptr)
invoke GetTextExtentPoint32, dc, sptr, tmpDWORD, addr textWidth


и заработало!

Спасибо smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)