Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.11.08;
Скачать: CL | DM;

Вниз

Классы в DLL на Delphi и MSVC++ (бой продолжается)...   Найти похожие ветки 

 
ПЗ   (2008-10-01 22:28) [80]

Проще. Но я преследую чисто исследовательские цели. Буду продираться.

Вот например, если вышеупомянутый ClassID сделать stdcall то при возврате структуры m_id по-значению (a,b:Integer) компилятор вставляет в конце ret 8. То есть, он хочет освободить 8 байт стека, якобы выделенных под результат? Однако на сях thiscall в этом же случае ставит ret 4, хотя в стек кладет тот же 8-байтовый результат. Нельзя ли их как-нибудь помирить малой кровью?


 
Сергей М. ©   (2008-10-01 22:44) [81]


>  То есть, он хочет освободить 8 байт стека, якобы выделенных
> под результат?


С какого перепугу ?

Тебе ж устали уже долдонить - в стек при этом кладется 4 байта со значением self (это отнюдь не результат) и еще 4 байта со значением адреса, по которому следует записать 8-байтовый результат !

Вот эти 4 байта + 4 байта = 8 байт  и составляют ту самую 8-ку, которая фигурирует в ret 8 при  том самом stdcall...


 
Сергей М. ©   (2008-10-01 23:14) [82]


>  Однако на сях thiscall в этом же случае ставит ret 4, хотя
> в стек кладет тот же 8-байтовый результат.


Да не в стек результат кладется !

Кладется он по адресу, переданному 4-мя байтами, положенными в стек непосредственно перед вызовом. Эти 4 байта и удаляются с вершины стека при ret 4.

Т.е. _thiscall - это, получается, жуткая смесь под названием "Кошмар дельфиста", состоящая из

- C-fastcall - параметр this передается через РОН ecx, подобно тому как Делфи при pascal-fastacall передает self через РОН ebx

- stdcall  - прочие параметры передаются через стек справа налево по ссылке или по значению, в зависимости от контекста, балансировкой стека заведует вызываемый код


 
oxffff ©   (2008-10-02 19:57) [83]

Бой окончен.
Еще с того момента как
Slym ©   (15.09.08 12:41) [25].
oxffff ©   (16.09.08 15:55) [49]


 
ПЗ   (2008-10-02 21:12) [84]

Да не в стек результат кладется !
Кладется он по адресу, переданному 4-мя байтами, положенными в стек непосредственно перед вызовом. Эти 4 байта и удаляются с вершины стека при ret 4.

А как же тогда:

struct SClassID
{
ULONG a,b;   //8 байт!
}sid;
...
sid.a=0xFF00FF;
sid.b=0xAABBEE;

virtual SClassID ClassID()
{
   return sid;
}

Стек перед вызовом:
ESP = 0012DD34
0x0012DD34  38 dd 12 00
0x0012DD38  4d 88 7b 65  
0x0012DD3C  20 10 00 00  

Стек после вызова:
ESP= 0012DD38
0x0012DD38  ff 00 ff 00  <=sid.a
0x0012DD3C  ee bb aa 00  <=sid.b
0x0012DD40  00 00 00 00
0x0012DD44  e8 82 47 0d

Отчетливо наблюдаю свои FF00FF и  AABBEE  на вершине стека, при этом метод имеет RET 4.
В то же время, если паскалевский вариант с stdcall перешить на возврат класса (делфи их всегда возвращает как указатели):

function ClassID():TClassID;virtual;stdcall;

где

TClassID =class
a,b:LongWord
end;

То при компиляции имеем Ret 4 (self?) и на вершине стека остается лежать 4 байта – указатель на экземпляр класса TClassID, который возвращается по ссылке.:
ESP=$0012DD38

0012DD40 00000000
0012DD3С 00001020
0012DD38 657B884D    <=Указатель на экземпляр  TClassID

Прошу сильно не пинать, если в очередной раз глупость спрашиваю.


 
oxffff ©   (2008-10-02 21:32) [85]


> ПЗ   (02.10.08 21:12) [84]


С++ вызов вызывается thisCall.

virtual SClassID ClassID()
{
  return sid;
}

2 параметра.
Ecx-указатель на экземпляр.
и указатель на возврат значения в стеке. Таким образом нужно вычистить только 4 байта. Поэтому ret 4.
Если бы результат мог уместиться в 4 байта, то возврат был бы через регистр.

В Delphi

TClassID =class
a,b:LongWord
end;

В Delphi в стек ложится только только self, а возврат осуществляется через регистр, поскольку умещается в регистре 4 байта.

Если ты сделаешь

TClassID =record
a,b:LongWord
end;

В Delphi в стек ложится , и указатель на результат поскольку не помещается в регистр, поэтому будет 8.

P.S. Я тебе функцию-обертку написал.  
oxffff ©   (16.09.08 15:55) [49]
Используй ее. И не нужно будет задумываться.


 
Slym ©   (2008-10-03 04:52) [86]

oxffff ©   (02.10.08 21:32) [85]
И не нужно будет задумываться.

У него научный интерес... а доводы окружающих это простой и ненаучный рефератизм


 
ПЗ   (2008-10-04 20:24) [87]

Все понял,в сем спасибо.


 
GrayFace ©   (2008-10-04 22:18) [88]

oxffff ©   (16.09.08 15:55) [49]
Data Execution Protection будет ругаться. Для таких вещей приходится использовать VirtualAlloc с указанием флага EXECUTE.


 
oxffff ©   (2008-10-04 23:04) [89]


> GrayFace ©   (04.10.08 22:18) [88]


Если процессор не поддерживает NX бит страницы, то увсе будет ок.


 
oxffff ©   (2008-10-04 23:07) [90]


> GrayFace ©   (04.10.08 22:18) [88]


Есть еще VirtualProtect.



Страницы: 1 2 3 вся ветка

Текущий архив: 2009.11.08;
Скачать: CL | DM;

Наверх




Память: 0.62 MB
Время: 0.024 c
2-1253771858
Knight
2009-09-24 09:57
2009.11.08
Можно снять изображение с формы как-то ещё кроме GetFormImage?


1-1221328691
ПЗ
2008-09-13 21:58
2009.11.08
Классы в DLL на Delphi и MSVC++ (бой продолжается)...


15-1252699551
DVM
2009-09-12 00:05
2009.11.08
День программиста утвержден!


2-1253006175
Гость
2009-09-15 13:16
2009.11.08
Проверить создан ли объект


15-1252653672
KSergey
2009-09-11 11:21
2009.11.08
SSI+PHP