Поиск:

Ответ в темуСоздание новой темы Создание опроса
> встроенный асм, обработка исключений, на mingw 
V
    Опции темы
victor79
Дата 21.12.2008, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


программист
*


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

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



создаю код для обработки конструкции finally при исключениях:
Код

int doexceptedfinally(void) {}

#define finally(addr) \
   __asm__ ("pushl %0;     \
             pushl %%ebp;  \
             pushl %1;     \
             pushl %%fs:0; \
             movl  %%esp,%%fs:0;" \
             : : "g" (addr), "g" ((void*)&doexceptedfinally));

int test_finally1(void) {
      finally(&&end);
      *(int*)0 = 1;
      printf("это сообщение не возникнет\n");
end:
      printf("сообщение в test_finally1\n");
}

при компиляции получается такой код:
Код

        .file   "5.c"
        .text
.globl _doexceptedfinally
        .def    _doexceptedfinally;     .scl    2;      .type   32;     .endef
_doexceptedfinally:
        pushl   %ebp
        movl    %esp, %ebp
        popl    %ebp
        ret
        .section .rdata,"dr"
LC0:
        .ascii "\355\342\256 \341\256\256\241\351\245\255\250\245 \255\245 \242\256\247\255\250\252\255\245\342\12\0"
LC1:
        .ascii "\341\256\256\241\351\245\255\250\245 \242 test_finally1\12\0"
        .text
.globl _test_finally1
        .def    _test_finally1; .scl    2;      .type   32;     .endef
_test_finally1:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
/APP
        pushl $L3;
        pushl %ebp;
// сохраняется адрес вызова текущего обработчика
        pushl $_doexceptedfinally;
// сохраняется адрес EXCEPTION_REGISTRATION предыдущего обработчика
        pushl %fs:0;
// устанавливается новый обработчик
        movl  %esp,%fs:0;
/NO_APP
        movl    $1, 0
// !!!! портится адрес предыдущего обработчика !!!
//   т.к. он сейчас на вершине стека, а компилятор кажется не знает этого
        movl    $LC0, (%esp)
        call    _printf
L3:
        movl    $LC1, (%esp)
        call    _printf
        leave
        ret
        .def    _printf;        .scl    2;      .type   32;     .endef

здесь добавлены комментарии для понятности асмовского кода, и общая суть, что компилятор не знает, что я добавлял в стек значения и затирает в данном случае последнее добавленное (см комментарий к асм-коду). В результате остается корректным лишь последний добавленный обработчик.
Вопрос: как сказать компилятору, что бы он эту процедуру оптимизировал каким-либо подходящим образом для этого случая?
PM MAIL WWW   Вверх
A1ukard
Дата 21.12.2008, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Лучше всего будет воздержаться от использования асма в программах на C++.
Ваша программа не будет компилироваться, если компилятор не знает синтаксиса AT&T. Также другой компилятор под другой платформой скорее всего также соберет программу неправильно (что-нибудь затрет в стеке). Использовать метки и goto тоже не рекомендуется.

В C++ есть миханизм обработки исключений. Для чего нужен finally, если программа так или иначе продолжит свое выполнение, покинув try-блок?


Если уж ну очень хочется покодить на асме, то пишите ассемблерные куски в виде функций и подключайте к программе в виде библиотек.
PM MAIL   Вверх
jonie
Дата 21.12.2008, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

Вопрос: как сказать компилятору, что бы он эту процедуру оптимизировал каким-либо подходящим образом для этого случая?
есть подозрение что никак. можно, конечно, взять исходники компилятора и поковырять их.... но это будет уже не С++.... да и вообще, для чего сий код может понадобиться? ...
этот код получится очань зависимым от реализации компилятора, и собственно, платформы...


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
victor79
Дата 21.12.2008, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


программист
*


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

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



у меня си, а не си++, и компилиться будет только под mingw, для одного проекта.
в си нету компиляции блоков try.
PM MAIL WWW   Вверх
Lazin
Дата 21.12.2008, 19:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



вы сначала изобретаете исключения, затем эмулируете классы, затем RTTI, проще сразу использовать с++
поскольку используется mingw, речь идет о windows, а на этой платформе есть механизм SEH, логично использовать его
PM MAIL Skype GTalk   Вверх
A1ukard
Дата 21.12.2008, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ну в данной ассемблерной вставке именно SEH для перехвата исключений и используется.
MinGW, если память не изменяет, С++ тоже компилит, потому отчего бы не заюзать try?

Или напишите в MASM функцию, которая в качестве аргумента принимает указатель на callback процедуру. если происходит ошибка, функция возвращает отрицательное число, иначе - ноль.

получится что-то вроде

Код

if(catch_exception(&my_prog, &arg_struct)) {
  printf("поймана ошибка\n");
}

printf("а это - наш finally\n");

PM MAIL   Вверх
victor79
Дата 21.12.2008, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


программист
*


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

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



кстати в mingw есть библиотека excpt.h, где макросы __try1 и __except1 именно такой ошибочный способ и использую - создают EXCEPTION_REGISTRATION в стеке через push.
PM MAIL WWW   Вверх
mes
Дата 21.12.2008, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



victor79, может это поможет:
http://www.insidepro.com/kk/014/014r.shtml
http://www.securitylab.ru/contest/212085.php

Это сообщение отредактировал(а) mes - 21.12.2008, 21:22


--------------------
PM MAIL WWW   Вверх
victor79
Дата 21.12.2008, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


программист
*


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

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



to mes, я еще вчера хотел у вас на плюсик в репутации нажать, да меня обломало - меньше 100 сообщений)
за пару минут до вашего сообщения я вспомнил про функцию alloca - выделение памяти в стеке, а после в одной из ваших ссылок - что можно же просто объявить переменную вида int buf[4]. Теперь дополнив это еще вчерашней ссылкой про расширение C (http://linfoline.homedns.org/gcc27/gcc1-4.html) у меня есть весь необходимый инвентарь для создания собственного обработчика исключений. Как доделаю, выложу на обсуждение - вдруг кому-нибудь понадобиться. Спасибо.
PM MAIL WWW   Вверх
Lazin
Дата 21.12.2008, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

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



подобные механизмы обработки исключений, лично меня ломают, так как я пишу на с++, а это поломало бы там абсолютно все, но для си может и сработать... хотя все-же лучше использовать то что предостовляется компилятором, так как это будет переносимо, плюс это не только ты один будешь использовать. не знаю как насчет mingw, а сишный компилятор фирмы microsoft умеет исключения и знает __try и __finally, может лучше использовать его?
PM MAIL Skype GTalk   Вверх
SABROG
Дата 22.12.2008, 00:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

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



Цитата(Lazin @  21.12.2008,  19:57 Найти цитируемый пост)
поскольку используется mingw, речь идет о windows, а на этой платформе есть механизм SEH, логично использовать его 


Имхо наоборот не логично, используют mingw обычно для кроссплатформенных проектов. В принципе и под линуксом mingw работает, т.е. собирает программы для windows. Но все-таки использование вставок asm'a это привязка к конкретному компилятору и конкретно к семейству процессоров.

Милая аватарка  smile 


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | GNU toolchain | Следующая тема »


 




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


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

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