Re[3]: реверс функции - надо узнать оригинал
От: Кодт Россия  
Дата: 19.05.10 08:21
Оценка: 6 (1) +1
Здравствуйте, disasm, Вы писали:

А>>>над первым арументом(arg0) кроме тех действий что я описал выше в функции, не происходит.

А>>>тоесть он используеться именно два раза как конструктор и далее возращаеться на выходе из функции

К>>Примерно так должна работать функция, возвращающая объект по значению.

К>>Вызывающая сторона выделяет у себя на стеке память под временный объект и отдаёт указатель в функцию.
К>>Функция в точке return (либо, если сделана оптимизация NRVO, в точке создания локального объекта) делает placement new и вызывает конструктор для данного указателя.

D>не совсем понял...


Поясняю ещё раз
// в исходном коде
Some foo()
{
  if(...)
    return Some(xxxxx);
  else
    return Some(yyyyy);
}

void bar()
{
  foo().buz(); // Some::buz
}

// как это на самом деле
Some* foo(void* buf)
{
  if(...)
    return new(buf) Some(xxxxx); // гуглить "placement new" !!!
  else
    return new(buf) Some(yyyyy);
}

void bar()
{
  char buf[sizeof(Some)];
  Some* tmp = foo(buf);
  tmp->buz();
  tmp->~Some();
}



К>>Ну и правильно. Сколько разных объектов функция возвращает, столько разных конструкторов и вызывается.

К>>Они же вызываются не вместе, а вместо друг друга. if-then-else.

D>да! но перед ними и после них есть определенные действия с разными переменными


Some foo()
{
  if(...)
  {
    Another var;
    .....
    Some x(xxxxx); // гуглить NRVO
    .....
    return x; // var.~Another()
  }
  else { ..... }
}



К>>Я точно не смотрел, как у известных мне компиляторов выглядит конвенция вызова функций, возвращающих объект.

К>>Очень может быть, что они уподобляются всяким strcpy: указатель на буфер на входе, указатель на тот же буфер на выходе.

D>GNU C++

D>обьект возращаеться через EAX

Этого недостаточно. Нужно выяснить — в каком порядке передаются аргументы в конвенции thiscall у функции, возвращающей объект по значению.
Возможно, this идёт вторым, а не первым параметром (первым идёт указатель на буфер возвращаемого объекта).


D>временный обьект был нужен

D>вот пример использование sub_8

Для всех будет лучше, если ты перестанешь делать вид, что объекты передаются по ссылке. Если там указатели — значит указатели.
"Объект передаётся в EAX" — глупости или жесточайшая оптимизация (когда размер объекта равен 4 и у него тривиальные конструкторы-деструкторы).

И не забывай оборачивать код в тэги [c]-[/c].
D>D::somefunc()
D>{

D>  B tmp2;// стековая переменная
      // конструктор здесь вызывается? если нет - это не стековая переменная, а только буфер под неё

D>  sub_8(tmp2, m_tmp1); // m_tmp1 это обьект A член класса D

D>  // думаю очень похоже на оператор и тогда 
D>  //вместо sub_8(tmp2, m_tmp1); было бы tmp2 << m_tmp1;
       // это очень похоже на tmp2 = sub_8(*m_tmp1);

D>  printf("%s\n", tmp2.GetStr());

D>  tmp2.~B();
D>}


D>это то, что можно понять при дизассемблировании


А>>>помогите идентифицировать функции, и если можно пример ее использования


К>>Варианты сигнатур

К>>class B { ..... };

К>>class A {
К>>  .....
К>>  static B sub8_v1(A* otherA) { return cond ? B(xxxxx) : B(yyyyy); }
К>>  B sub8_v2(/*this*/) { return cond ? B(xxxxx) : B(yyyyy); }
К>>  // для извращенцев
К>>  static B* sub8_v3(char* raw, A* otherA) { return cond ? new(raw)B(xxxxx) : new(raw)B(yyyyy); }
К>>  .....
К>>};

D>замысловато, но тоже сильно накручено
Это была иллюстрация

D>поскольку там нет ни одного оператора new


placement new не вызывает ::operator new(size_t).
А ::operator new(void*,size_t) тривиальный, и компилятор его мысленно сократил. И правильно сделал.


К>>Ещё есть подозрения на виртуальное наследование A от B. Тогда sub8 — это, возможно, конструктор: он там довольно хитро устроен.

D>нет, виртуального наследование точно нет

D>я все более полагаюсь на то что это какойто оператор<<

D>но констуркторы в теле меня очень смущают

Попробуй всё более полагаться на возврат объекта по значению.
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.