Форум: "Основная";
Текущий архив: 2009.11.08;
Скачать: [xml.tar.bz2];
ВнизКлассы в 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;
Скачать: [xml.tar.bz2];
Память: 0.61 MB
Время: 0.009 c