Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вызов функции извне 
V
    Опции темы
ParaPik
Дата 16.4.2011, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 8.1.2009

Репутация: нет
Всего: нет



Есть код:
Код

WORD __declspec(dllexport) __cdecl RunMTest(const wchar_t * str)
{
    HANDLE fin = CreateFile(str, GENERIC_READ, FILE_SHARE_READ, nullptr,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
    if (GetLastError() == ERROR_FILE_NOT_FOUND)
        return -1;
    typedef unsigned char byte;
    vector<byte> func;    
    char bt = 0;
    DWORD numRead = 0;
    while (ReadFile(fin, &bt, 1, &numRead, nullptr))
    {
        if (numRead == 0)
            break;
        func.push_back(bt);
    }
    CloseHandle(fin);
    
    
    void * _p = func.data();
    times.push_back(0);
    DWORD ID = times.size() - 1;
    SetTimer(nullptr, ID, USER_TIMER_MINIMUM, TimerFunc);
    __asm
    {
        push edx
        mov edx, _p // здесь вылетает ошибка Access Violation
        call edx
        pop edx
    }
    
    KillTimer(0, ID);
    return times[ID];    
}


Не могу разобраться, почему возникает эта ошибка. В файле, который считывает функция, содержит откомпилированную инструкцию RET(для пробы), т.е. 1 байт. Помогите понять, в чем дело.
PM MAIL   Вверх
xvr
Дата 16.4.2011, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



В x86 не всякие данные можно исполнить. То, что исполняется должно быть помещено в исполняемый сегмент.
Смотри DEP
PM MAIL   Вверх
Dem_max
Дата 16.4.2011, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

Репутация: 16
Всего: 39



хорошим прявилом программирования является не использование asm вставок 


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
ParaPik
Дата 17.4.2011, 11:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 8.1.2009

Репутация: нет
Всего: нет



А есть какой-нибудь другой способ запустить на исполнение код из файла? При компиляции в Visual Studio этот код не хочет работать, но если откомпилировать в C++Builder, то все нормально.(когда-то давно это делал, а сейчас только решил использовать этот код) Не хочется ради одной функции ставить другую IDE.
Цитата

хорошим прявилом программирования является не использование asm вставок

Далеко не во всех случаях. Простой пример: перевести число в строку в двоичном виде. Код, решающий эту проблему и написанный самостоятельно на asm, будет в разы быстрее нежели аналог, например, на C.

PM MAIL   Вверх
borisbn
Дата 17.4.2011, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



Цитата(ParaPik @  17.4.2011,  11:03 Найти цитируемый пост)
од, решающий эту проблему и написанный самостоятельно на asm, будет в разы быстрее нежели аналог, например, на C.

ОМГ, ещё один "мистер быстрее компилятора"...
Представить доказательство, что код на Си++ (на MSVC 2010, например) медленнее твоего велосипеда - религия не позволяет ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
ParaPik
Дата 17.4.2011, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 8.1.2009

Репутация: нет
Всего: нет



А я разве могу, используя средства C++, узнать напрямую состояние флага CF? Это процедура перевода будет использовать только команды shr и jc. Используя C++, максимум, что я смогу использовать, это инструкцию div, которая медленнее shr. Первый вариант будет быстрее. 
Вот на asm:
Код

mov eax, var
@label:
cmp eax, 0
jz @exit
shr eax, 1
jc @one
mov cl, 0
jmp @func
@one
mov cl, 1
@func:
call Insert
jmp @label
@exit:

Вариант на C++ будет длиннее.
PM MAIL   Вверх
borisbn
Дата 17.4.2011, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



ParaPik, не знание (твоё) Си++ не освобождает от ответственности...
Код

for ( int i = 0; i < sizeof( int ) * 8; ++i ) {
    Insert( var & 1 ); // это твой call Insert
    var >>= 1; // вот это - твой shr
}

а теперь давай спорить на пиво, что твой вариант медленнее этого, скомпилированного последней версией gcc или MSVC 2010 с опцией /O2


можно непонятнее, но ещё короче и, наверное, быстрее
Код

for ( ; var; var >>= 1 )
    Insert( var & 1 );


Это сообщение отредактировал(а) borisbn - 17.4.2011, 14:39


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
ParaPik
Дата 17.4.2011, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 8.1.2009

Репутация: нет
Всего: нет



1) Я схватил первый попавшийся пример(алгоритм его решения на C++ был не самый лучший).
2) Рассмотрел его с отключенной оптимизацией. Ясен пень, что с включенной оптимизацией компилятор всегда заметит то, чего не смог заметить человек.
3) 
Цитата

не знание (твоё) Си++ не освобождает от ответственности...

Не утверждай того, чего не знаешь. И пробуй иногда для себя отдираться от сторонних оптимизаторов. 
4) Не спорю, в моем варианте тоже есть моменты, которые можно оптимизировать. 
5) И у кого-то проблемы с восприятием текста. Какая проблема рассматривается в теме? Единственный, кто ответил, в чем проблема, был xvr. Жаль, что он не предложил альтернативный вариант решения. Остальная болтовня о том, нужны ли asm вставки или нет, вообще, честно говоря, не относится к теме. Поэтому если есть проблемы с восприятием текста или нет дельного совета, просьба - НЕ ЗАСОРЯТЬ тему.

Это сообщение отредактировал(а) ParaPik - 17.4.2011, 18:42
PM MAIL   Вверх
borisbn
Дата 17.4.2011, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



Цитата(ParaPik @  17.4.2011,  17:46 Найти цитируемый пост)
Не утверждай того, чего не знаешь. 

просто делаю выводы. из этого
Цитата(ParaPik @  17.4.2011,  14:27 Найти цитируемый пост)
Используя C++, максимум, что я смогу использовать, это инструкцию div


Цитата(ParaPik @  17.4.2011,  17:46 Найти цитируемый пост)
И пробуй иногда для себя отдираться от сторонних оптимизаторов.

я, какбэ, сам знаю, что мне пробовать, а что нет.


по теме: см. функцию VirtualProtect
с третьим параметром PAGE_EXECUTE_READWRITE


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
ParaPik
Дата 17.4.2011, 19:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 8.1.2009

Репутация: нет
Всего: нет



А вот теперь спасибо. Все работает. smile 

Это сообщение отредактировал(а) ParaPik - 17.4.2011, 19:35
PM MAIL   Вверх
xvr
Дата 17.4.2011, 19:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(ParaPik @  17.4.2011,  17:46 Найти цитируемый пост)
Жаль, что он не предложил альтернативный вариант решения. 

С VirtualProtect вы уже сами разобрались, а по поводу asm вставки - она тут лишняя
Код

    void * _p = func.data();
/*
    __asm
    {
        push edx
        mov edx, _p // здесь вылетает ошибка Access Violation
        call edx
        pop edx
    }
*/
 (  ( void (*)() ) _p )   (); // Это ваша asm вставка на голом С


PM MAIL   Вверх
ParaPik
Дата 17.4.2011, 20:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 132
Регистрация: 8.1.2009

Репутация: нет
Всего: нет



Спасибо за ответ, xvr. Я знаю, что есть аналог asm-вставки на C, который вы и предложили. Здесь оно, все равно, непринципиально.
Поправьте меня, если я немного не так понял, xvr: вы придрались к asm-вставке, потому что код не должен быть привязан к командам конкретной машины(т.е. чтобы код был привязан только к C++ компилятору)?
PM MAIL   Вверх
xvr
Дата 18.4.2011, 08:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(ParaPik @  17.4.2011,  20:02 Найти цитируемый пост)
Поправьте меня, если я немного не так понял, xvr: вы придрались к asm-вставке,

К asm вставке прелирался не я, а Dem_max. Но в общем и целом я с ним согласен - asm вставка оправданна только тогда, когда ее действие нельзя выполнить эквивалентным по объему С/С++ кодом.
Это может быть и доступ к недоступным с С уровня регистрам, и оптимизация по скорости критичных участков программы, но явно не банальный вызов процедуры по указателю. Язык С предоставляет такой сервис штатно  smile 
PM MAIL   Вверх
500mhz
Дата 18.4.2011, 09:48 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


шайтан
***


Профиль
Группа: Завсегдатай
Сообщений: 1017
Регистрация: 5.5.2008
Где: Киев / Italy

Репутация: 3
Всего: 14



Код

 (  ( void (*)() ) _p )   (); // Это ваша asm вставка на голом С


а вы листинг асмовский ее видели?


--------------------

PM MAIL ICQ   Вверх
borisbn
Дата 18.4.2011, 10:06 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 6
Всего: 135



500mhz, 
Код

char * _p = 0;
(  ( void (*)() ) _p )   ();

Код

; 7    : char * _p = 0;
    mov    DWORD PTR __p$[ebp], 0
; 8    : (  ( void (*)() ) _p )   ();
    call    DWORD PTR __p$[ebp]

и что ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0600 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.