Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
2-1253654979
Евгений Р.
2009-09-23 01:29
2009.11.08
Использование $IFDEF


2-1253670540
Время
2009-09-23 05:49
2009.11.08
подсчет времени


2-1253272954
Mishenka
2009-09-18 15:22
2009.11.08
Какой тип параметра выбрать для передачи Memo поля в ADOStorProc


2-1253990678
faiwer
2009-09-26 22:44
2009.11.08
Вопросы по поводу Scroll-а


15-1252528212
Юрий
2009-09-10 00:30
2009.11.08
С днем рождения ! 10 сентября 2009 четверг





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский