Начало программирования.

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

  1. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Ладно, признаю, тут я погорячился маленько :)
     
  2. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    Нет.


    Не соглашусь, досрочный выход бывает полезен, например функция для проверки правильности многих параметров.
    Код (Text):
    1. result:=false;
    2. if NOT <проверка параметра 1> then Exit;
    3. if NOT <проверка параметра 2> then Exit;
    4. ...
    5. result:=<проверка последнего параметра>
    А насчет Break в case +1, всегда удивлялся кому это нужно, чтобы кейс не брейкался.
     
  3. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    CyberManiac
    Почему ж, существуют, и не так уж и мало. Нужна приличная базовая подготовка. Ну а Фортран или Си++ -- не такая уж большая разница, если голова на плечах есть, и она не пуста :)

    Согласен. Однако применительно к оператору выхода из функции с возвратом значения и исключения как такового не потребуется: он должен быть способен возвращать в том числе и динмассивы. Естественно, ему такой массив должен быть задан в виде переменной (ну или функции, результатом которой будет динмассив).

    Не такой уж и редкий. Во всяком случае, мне не нравится нагромождение условных операторов, и отбивание их пробелами тут роли не играет (отбиваю я пробелы, отбиваю). И я предпочитаю использовать Exit, если работа функции реально закончилась. Кстати, ИМХО, это повышает читабельность, а отнюдь не снижает: видишь Exit -- и сразу понимаешь, что процедура всё, закончила работу, и нет нужды пытаться вникнуть, а не продолжается ли её выполнение где-то дальше.

    Ursus
    На чём написано ядро Линуха? На чём написан, кажется, ГНОМ (или КДЕ?)? Так что действительно погорячились :)
     
  4. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    А я неоднократно сталкивался с обратным эффектом, и в Паскале (ох и давно это было) и в С++ и конечно в моём любимом асме периодически бывает что компилятор начинает заявлять о несуществующей синтаксической ошибке, начинаешь разбираться внимательнее - обнаруживаешь там ошибку в логике кода, исправляешь и мистическая синтаксическая ошибка бесследно исчезает :)) причём искуственно воспроизвести ситуацию чтобы она опять возникла в правильном коде и позволила обвинить компилятор в ложных ошибках не удаётся :)) потому как он прав :))
     
  5. beginner

    beginner New Member

    Публикаций:
    0
    Регистрация:
    18 янв 2008
    Сообщения:
    233
    Ursus, GoldFinch
    признаюсь, есть ошибки в коде
    вот исправленный код, позволяющий осуществить приведение указателя метода класса к char* и осуществляющий сплайсинг.
    Код (Text):
    1. class AAA {
    2. public:
    3.     int x;
    4.     AAA(int i);
    5.     ~AAA();
    6.     int get(void);
    7. };
    8. AAA::AAA(int i) {x=i;};
    9. AAA::~AAA() {};
    10. int AAA::get(void) {return x;};
    11.  
    12. int myFunc(void) {
    13.     return 5;
    14. };
    15. { //в функции мейн такой код:
    16.     AAA obj(1); // создаем объект и полю x присваиваем 1
    17.     int y = obj.get(); // возращает 1, так как обычный вызов метода класса.
    18.     char *s = new char[5];
    19.     char buff[1024];
    20.     wsprintf(buff, "%p", &AAA::get); // получаем адрес переходника
    21.     DWORD addr = strtol(buff, NULL, 16); // в хекс-виде
    22.     s = (char*)addr; // вот собственно само приведение типа указателя к char*
    23.     DWORD addrFunc = (DWORD)myFunc;
    24.     DWORD oldFlags;
    25.     VirtualProtect((LPVOID)s, 5, PAGE_EXECUTE_READWRITE, &oldFlags); // даем добро на перезапись в сегменте кода
    26.     s[1] = 0x4A + 0x19; // ну тут надо смещение высчитывать самому, у всех будет разное
    27.     y = obj.get(); // снова вызываем метод класса, но в результате будет 5 :) чудеса да и только :)
    28. // единственное что нужно учесть, что перед вызовом метода класса в стек кладется указатель на обьект.
    29. // и в релизной компиляции могут быть так же другие смещения.
    30. }
    вот она гибкость языка. с помощью функций и приведения типов сделал простейший сплайсинг
     
  6. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    beginner
    а без wsprintf(buff, "%p", &AAA::get) ?
     
  7. beginner

    beginner New Member

    Публикаций:
    0
    Регистрация:
    18 янв 2008
    Сообщения:
    233
    GoldFinch
    может еще без функции main?
    или без обьявления класса?
     
  8. Diakon

    Diakon New Member

    Публикаций:
    0
    Регистрация:
    26 июн 2008
    Сообщения:
    27
    Флуд развели. Ну скажите что можно сделать на С# чего нельзя сделать в Делфи и встроенного в него асма? Для меня Делфи понятен и я сомневаюсь что число программистов, которым не хватает возможностей любого высокоуровневого языка превышает 5% от их общего кол-ва. А разговоры о меньшем кол-ве строк или места при ресурсах современных компов - бессмыслица, если только вы не занимаетесь написанием вирусов
     
  9. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Ну как тебе сказать...
    Твой код делает (ну, или, по крайней мере, ты рассчитываешь на то, что он это делает) абсолютно то же самое, что строка

    Код (Text):
    1. char *s = (char*)&AAA::get;
    но делает это через ж%у, уж извини за выражение :)

    Но проблема даже не в этом. Проблема в том, что именно в том случае, о котором говорит GoldFinch, этот код (и твой, и тот, что я привел) работает не так, как требуется (там случай с множественным виртуальным наследованием, если мне не изменяет склероз). Вотъ...
     
  10. beginner

    beginner New Member

    Публикаций:
    0
    Регистрация:
    18 янв 2008
    Сообщения:
    233
    Ursus
    строка
    char *s = (char*)&AAA::get;
    не работает, так же как и
    DWORD dw = (DWORD)AAA::get;
    GoldFinch знал об этом, когда просил написать код. Иначе бы он не просил бы :)
    Замена одной строчки кода тремя - ну не знаю, трудно назвать это решение через одно место.
    Там где цикл for с непростыми параметрами заменили на цикл while в паскале - я тоже могу назвать решением через одно место.

    Про множественное виртуальное наследование не было речи в посте №250 http://wasm.ru/forum/viewtopic.php?pid=279453#p279453

    Не хотите ли привести пример решения данной задачи на паскале?
     
  11. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Хорошо, давай разбираться.
    Что, по-твоему, происходит в этом куске

    Код (Text):
    1. wsprintf(buff, "%p", &AAA::get); // получаем адрес переходника
    и чем это отличается от

    Код (Text):
    1. char *s = (char*)&AAA::get;
    А "через ж%у" - это получение строкового представления адреса только для того, чтобы в тут же восстановить числовое значение из этой строки посредством strtol()
     
  12. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Не хочу. Паскаль для таких вещей не предназначен. Ограничения синтаксиса тут выросли отнюдь не на пустом месте.
     
  13. beginner

    beginner New Member

    Публикаций:
    0
    Регистрация:
    18 янв 2008
    Сообщения:
    233
    Ursus
    при
    char *s = (char*)&AAA::get;
    студия выдает ошибку:
    "Error 1 error C2440: 'type cast' : cannot convert from 'int (__thiscall AAA::* )(void)' to 'char *' f:\work\wasm_ntp_\wasm_ntp_\bred.cpp 43 wasm_ntp_"
    Я так понял, это связано с тем, что функция является членом класса, потому как обычные функции работают на ура.
    немножко покурил статью:
    http://www.developing.ru/com/compilation_theory.html и поработав с отладчиком, выяснил, все таки адрес метода получить возможно.
    Ведь обычный метод класса - это обычная функция по определенному адресу, а значит получить ее адрес вполне возможно.
    Вот решил обойти это ограничение.

    Там дальше в статье обсуждают уже таблицу виртуальных функций, тока мне это уже было не интересно.

    // ушел спать, завтра посвободе выйду.
     
  14. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Хорошо, я тоже туплю :)
    Изменяем пример

    Код (Text):
    1. char *s = (char*)(void*)&AAA::get;
    Теперь компилируется? (если нет - на этот раз полезу уже сам пробовать :)

    Но ответь на главный вопрос:
    Что происходит в строке

    Код (Text):
    1. wsprintf(buff, "%p", &AAA::get);
     
  15. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    тоже не работает
     
  16. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
  17. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Ладно, я таки полез в стандарт :)
    Не работает, потому как не должно.

    Работает вот это, но это - грязный хак

    Код (Text):
    1. union{
    2.         int (__thiscall AAA::*pp)(void);
    3.         void* v;
    4.     }e;
    5.  
    6.     e.pp = &AAA::get;
    7.     char* p = (char*)e.v;
    но, повторюсь, синтаксические ограниченя языка не на пустом месте растут.
     
  18. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    если указатель на метод 32разрядный, ничто не должно мне мешать привести его к любому другому 32разрядному указателю или 32разрядному числу вообще %)
     
  19. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    reinterpret_cast ?
    понятно, что в случае необходимости каста к войду он уже не поможет, как выше грамотно заметил Ursus.
    GoldFinch
    вы много таких языков знаете, которые позволяют это?
     
  20. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Не, если C-style cast нельзя сделать, то и reinterpret_cast тут не поможет.