Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Мнение по указателям в рамках отдельных процедур, ИМХО на всю тему... просто мысли вслух 
:(
    Опции темы
En_t_end
Дата 22.6.2005, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



Вот внезапно в голову забралась мысль smile Ведь используя в функциях указатели, мы тем самым обрекаем на практически вечное существование стеки этих функций... То есть был к примеру указатель temp, указывающий на переменную типа int, обьявленную в этой функции. По идее когда процедура заканчивается, все переменные вместе со стеком уничтожаются, память отчищается. Но... если мы возвратим наш указатель в этой функции, то та переменная int, на которую сначала ссылался temp, а потом и какой-то другой указатель в другой процедуре будет жить, будет жить и стек. Теперь представим что функций 1000-и и каждые возвращают указатели char*. Хмм... что-то мне говорит, что такое использование указателей - это зло... потому что программа использует по сути ненужные стеки, на поддержание которых, вернее для работы с которыми тратиться лишняя память и процессорное время. В рамках простенького проекта это скорее не почувствовать, а точнее даже можно ощутить прирост производительности по сравнению с кустарным способ возвращения значения функции за счет существования меньшего числа потенциальных переменных, но в крупных программах я думаю есть шанс напороться на "обратную тягу".

PM MAIL ICQ Skype GTalk Jabber   Вверх
Дрон
Дата 22.6.2005, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 93



Цитата(En_t_end @ 22.6.2005, 18:21)
будет жить и стек

Не будет smile


--------------------
Да. Именно так.
PM   Вверх
En_t_end
Дата 22.6.2005, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



Дрон 
Чем докажешь ?
PM MAIL ICQ Skype GTalk Jabber   Вверх
Дрон
Дата 22.6.2005, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 93



С++ это не Java и не C#. Он ссылки на объекты не контролирует.


--------------------
Да. Именно так.
PM   Вверх
En_t_end
Дата 22.6.2005, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



Дрон
Я говорю про контроль НЕ ссылок, а переменных... они в таких точно не уничтожаются. Сам попробуй.
PM MAIL ICQ Skype GTalk Jabber   Вверх
Дрон
Дата 22.6.2005, 17:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java-ненавистник :)
****


Профиль
Группа: Участник Клуба
Сообщений: 3179
Регистрация: 29.12.2002
Где: Санкт-Петербург

Репутация: 10
Всего: 93



Цитата(En_t_end @ 22.6.2005, 18:28)
. они в таких точно не уничтожаются. Сам попробуй.

Что значит не уничтожается?

Память освобождается и некоторое время будет ещё хранить значения, пока её какая-нибудь функция не перезапишет.


--------------------
Да. Именно так.
PM   Вверх
_hunter
Дата 22.6.2005, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



если ты возвращаеш char* то где-то ( пусть в функции ) был new. вот эта _память_ и висит, но висит она не на стеке. а сам указатель возвращается по значению ( т.е. т он не висит... )


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
En_t_end
Дата 22.6.2005, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



Дрон
стек простейшего метода chat* tempo(void); - будет существовать, как мне кажется до тех пор, пока эта ссылка не будет обнулена: char *tempo_ptr = tempo(void); Согласен ?
PM MAIL ICQ Skype GTalk Jabber   Вверх
Mayk
Дата 22.6.2005, 17:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



En_t_End, проверь
Код

int* a()
{
    int tmp;
    static int counter=0;
    tmp=counter++;
    return &tmp;
}

int main()
{
   int *x,*y,*z;
   x=a(); y=a(); z=a();
   printf("%d %d %d\n",*x,*y,*z);
}


Следуя твоей логики должно быть выведено 0 1 2.
Следуя логики Си это совсем не так.


Добавлено @ 17:34
En_t_End
У функций НЕТ стека.
Стек один.


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
En_t_end
Дата 22.6.2005, 17:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



_hunter 
С new - это другой случай... там Си работает с динамической памятью - поэтому по сути указатель указыват на некоторую область памяти, причем стек функции не будет управлять ею. ИМХО
Добавлено @ 17:40
Mayk
Не понял... как это ? А как же вся та инфа, из которой я понял, что функция или процедура - это мини программа, соответсвенно... стек должен быть, как тогда реализовано управление переменными ? То что есть глобальный стек я не оспариваю.
Добавлено @ 17:41
Дрон
Бьярн Страуструп по моему писал, что ни одна переменная не будет уничтожена, пока на неё будет ссылаться указатель.
PM MAIL ICQ Skype GTalk Jabber   Вверх
comcon1
Дата 22.6.2005, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

Репутация: 12
Всего: 17



Посмотрим в ассемблер. Когда возвращается указатель перед вызовом функции стек смещается:

stack:.......................................перед вызовом:...........................................после call (вызов функции)
o|o|o|o|o|*........----->......... o|o|o|o|o|_memory_for pointer_| ---->...o|o|o|o|o|_memory_for_pointer_|_back_address_

далее в то место, где _memory_for_pointer_, записывается указатель. Мы выходим из функции:

команда ret Поп-ает адресс возврата. и смещает туда каретку...теперь мы делаем Pop и забираем результат.
o|o|o|o|o|_memory_for_pointer_.......................................------>.................................o|o|o|o|o|

Стек снова в исходном состоянии!!

Если хотите, можно подробнее. Но разницы в том, что возвращать, нет. Тока память разная в стеке отводится перед вызовом call

Это сообщение отредактировал(а) comcon1 - 22.6.2005, 17:48


--------------------
PM MAIL   Вверх
_hunter
Дата 22.6.2005, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



тогда я не понял что ты возвращаеш в своем указателе ( если ты под него память не выделяеш )...
но даже в таком случае вернется 4байта по значению и стек благополучно хрохнется


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
En_t_end
Дата 22.6.2005, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



_hunter
Вот пример... ну не скажешь же ты, что потом юзая в классе то что получу в результате этой функции я буду юзать призрака ?
Код

char *CPFClientDlg::Test()
{
char moment[21];
while(/**/){/**/} //Заполняем массив.
char *testing = moment; 
    return testing;
}


Это сообщение отредактировал(а) En_t_end - 22.6.2005, 17:57
PM MAIL ICQ Skype GTalk Jabber   Вверх
comcon1
Дата 22.6.2005, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

Репутация: 12
Всего: 17



Програма выполняется по мере считывания ее из памяти. Есть в регистрах процессора указатель на место, где мы считываем (кажется IP) Instruction Pointer.
Здесь дело в том, что в функцию мы входим (команда CALL). И в стек заносится аддресс IT того места, откуда мы прыгаем в функцию. Внутри функции мы производим некоторые операции и возвращаемся (команда RET). И ВЕРХУШЕЧНЫМ ЭЛЕМЕНТОМ ДОЛЖЕН БЫТЬ АДДРЕСС возврата в тело прораммы. Иначе будет RunTimeError.

Из-за этого в стеке сначала отводят память (смещая указатель на вершину, стек в процессоре в обр. направлении)
SUB SP, 04
SUB - вычесть.
SP - STACK POINTER.
А потом уже входим в функцию.
CALL 0AFFF (аддресс входа туда будет смещен IP)

Ну а когда мы вернулись - мы берем из стека значение и приводим его в исходное состояние. Никаких перегрузок.

Это сообщение отредактировал(а) comcon1 - 22.6.2005, 17:55


--------------------
PM MAIL   Вверх
_hunter
Дата 22.6.2005, 17:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



не скажу
потому что ты явно выделил память ( и никто короме тебя ее удаялть не будет )
а вот если где-то перед юзанеем сделаеш delete[] ( причем не обязательно tempo ) то именно призрака ты и получиш...


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Mayk
Дата 22.6.2005, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


^аВаТаР^ сообщение>>
****


Профиль
Группа: Участник
Сообщений: 2616
Регистрация: 22.5.2005
Где: за границей разум а

Репутация: 45
Всего: 134



En_t_end
Вот в том то и дело, что стэк один на всех во всем потоке программы. В него соответственно ВСЁ пихается.
Блин, попробую проиллюстрировать стек на примере той программы, что привел.
Предположим что в начальный момент времени main() стэк пуст
Предположим, что он растет к старшим адресам(это не так, но имхо так понятнее... Во всяком случае мне)

main(){ int x,y,z;
В стек добавляются локальные переменные
SS:0000 x
SS:0004 y
SS:0008 z
(SS - сегмент стека)

x=a();
SS:000c main+xx
...запускается a()
SS:0000 x
SS:0004 y
SS:0008 z
SS:000c main+xx

a() пихает в стек tmp(увеличивает значение стека на размер tmp)
tmp=0
tmp распологается по адресу SS:0010.
SS:0000 x
SS:0004 y
SS:0008 z
SS:000c main+xx
SS:0010 tmp
Функция возвращает указатель на tmp, то есть SS:0010.

Теперь a() завершается.
Она уничтожает ВСЕ локальные переменные(уменьшает значение стека на размер tmp)
Выпихивает main+xx, передает туда управление.
Всё это повторяется трижды.

Это сообщение отредактировал(а) Mayk - 22.6.2005, 18:00


--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
En_t_end
Дата 22.6.2005, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



comcon1
Значит все-таки в глобальном стеке значение полученное в результате работы функции и после конца работы сохраняется ?
PM MAIL ICQ Skype GTalk Jabber   Вверх
_hunter
Дата 22.6.2005, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



вот:
Код

int* someFunction(int test)
{
    int someVariable = test;
    return &someVariable;
}

#pragma argsused
WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    int data;
    data = 1;
    int* tmp1 = someFunction(data);
    data = 2;
    int* tmp2 = someFunction(data);
    return 0;
}

тебе илюстрация призрака...
tmp1 должен быть равным 1, tmp2 -- 2, но это не так


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
En_t_end
Дата 22.6.2005, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



_hunter
Я изменил пример, тот пример как раз был тем случаем с явным выделением памяти через new.
PM MAIL ICQ Skype GTalk Jabber   Вверх
comcon1
Дата 22.6.2005, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

Репутация: 12
Всего: 17



2 En_t_end. То, как мы ограничиваем понятие "функция" в С++ и то, как это реализовано в ASM - это разные вещи.
Кроме возвращаемых параметров, есть еще входные параметры, которые тоже передаются через стек. В ASM функция - это то, что идет между адрессом начала (куда нас кидает команда CALL) и командой RET, которая кидает нас обратно в тело программы. В С++-функцию (да и вообще функцию любого высокоуровневого языка) еще входят передача параметров перед CALL-ом и реанимация стека после RET-а.

Кстати, где-то я читал, что для корректного удаления объекта класса delete-ом нужно явно задавать деструктор.
С чем это связано?? Мож кто в курсе? Я вот просто разницы не вижу.

Это сообщение отредактировал(а) comcon1 - 22.6.2005, 18:08


--------------------
PM MAIL   Вверх
En_t_end
Дата 22.6.2005, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



Дык чего, если у меня пол функций в программе, как в примере у _hunter, то ни сегодня завтра все рухнет ? Что переделывать на явное выделение памяти ?
Добавлено @ 18:14
Ладно... я думаю тему можно удалять, ибо я наплел тут полную чушь, как и ожидал - пойду читать соответсвующую главу Страуструпа.
PM MAIL ICQ Skype GTalk Jabber   Вверх
_hunter
Дата 22.6.2005, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



в таком примере получиш призрака
+ посмотри мой пример.

comcon1, свой деструктор нужно писать только в случае явного выделения памяти ( потому что деструктор по умолчанию ( который компилятор в любом случае прикрутит ) просто не знает что с ней ( с памятью ) делать -- может ее оставить для чего-нить нужно )
Добавлено @ 18:16
En_t_end, если как у меня в примере -- странно что еще не рухнуло smile


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
comcon1
Дата 22.6.2005, 18:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

Репутация: 12
Всего: 17



Как можно оставить память после деструкции класса? Допустим я ничего не пишу в деструкторе. И делаю указателю на класс new-delete. Как мне обратиться к этой памяти? smile

Тему ни в коем случае не удалять, ибо отведение памяти - вопрос один из самых важных!!!

Это сообщение отредактировал(а) comcon1 - 22.6.2005, 18:25


--------------------
PM MAIL   Вверх
_hunter
Дата 22.6.2005, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



Цитата
Как можно оставить память после деструкции класса?

написать в конструкторе new (простейший пример )
Цитата
Как мне обратиться к этой памяти?

к какой? к классу?
SomeClass* someClass = new SomeClass();
someClass->SomeMethod();


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
comcon1
Дата 22.6.2005, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

Репутация: 12
Всего: 17



Да нет. Я не про это. Допустим,я создал объект
SomeClass *myclass = new SomeClass();
Чего-то сделал.
myclass->mymethod();
А теперь вызвал деструктор, .....
delete myclass;
.... в котором ничего не прописал.
Ты говорил, что память остается. Как после всего этого можно к ней обратиться, если она осталась??
Или если освобождения памяти не прописано в деструкторе, то после всех вышеперечисленных манипуляций, с классом можно продолжать работать??? smile


--------------------
PM MAIL   Вверх
_hunter
Дата 22.6.2005, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 16
Всего: 98



я же написал: память выделяется в конструкторе
т.е.
Код

SomeClass::SomeClass()
{
    someVariable = new...
}

если эту память потом не грохнуть в деструкторе она просто потеряется и доступ к ней ты не получиш...


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
comcon1
Дата 22.6.2005, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

Репутация: 12
Всего: 17



Все понятно. thx. Этих я удалять стараюсь. Забываю иногда, правда :-)


--------------------
PM MAIL   Вверх
En_t_end
Дата 22.6.2005, 19:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



Короче я тему удаляю, ибо я получил ответ на свой вопрос(ламерский), получил на свой и comcon1. Так как сама тема побуждает к флейму её стоит удалить. 
PM MAIL ICQ Skype GTalk Jabber   Вверх
vadims
Дата 22.6.2005, 19:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 305
Регистрация: 8.6.2005

Репутация: 2
Всего: 17




ИМХО: тут просто перемешали понятия

Для простоты считаем приложение 16-битным и int(teger) имеет размерность 2 байта, а указатель 4 байта

--------------------------------------------------------------------------------------------------
(1)
Память делиться
а. сегмент(ы) кода - CS:IP
б. cтек (один для всех) - SS:SP
в. глобальный cегмент данных - один для всех глобальных переменных и переменных типа static
г. дополнит. глобальные сегменты данных - свой для каждой пременной/массива типа far и huge
д. куча локальная и глобальная

локальные переменные функции
void f( void )
{
int a,b;
char mas[100];
...

}
резервируются в стеке

; те после сохранения регистров внутри функции
push di
push si

; идет собственно резервирование
sub SP, 104 ; 2+2+100
mov bp, SP
; работа с переменными идет через SS:[bp+смешение до переменной]

. . .

; возвращаем стеку зарезервированную область
add SP, 104
pop si // восстанавливаем регистры
pop di
ret // возврат


те по возвращению из функции, все локальные переменные описанные в ней по сути уже неопределены, хотя физически их значения остаются;
там уж зависит от того насколько последующий код использует стек

Один нюанс, если локальная переменная описана как static, то она распологается в глобальном сегменте данных и именно поэтому
ее значение корректно при повторном входе в функцию
Что собственно можно проверить на примере приведенном Mayk,
рез-тат будет 2 2 2


То что получаем через new - в куче, от функции не зависит
Хотя опять нюансы - если будет выделено в локальной куче, то этот участок памяти все равно освободиться по завершению программы, если в глобальной то после перезагрузки. Лучше не рисковать и освобождать обязательно

--------------------------------------------------------------------------------------------------
(2)

Существует 2 подхода к вызову процедур/функций, передаче аргументов и возврату значений

Делаем мне скидку на то что немного подзабыл синтаксис паскаля и ассемблер


1. Паскалевский -

func( integer a,b, var integer ra, rb ) : pointer

ptr = func( 1, 2, ra, rb);

при вызове
а) входные параметры в стек, начиная с последнего
б) выходные параметры будут возвращены тоже ч/p стек, для чего перед вызовом SP уменьшается на размер необходимый для их хранения,
в нащем случае (ra,rb и возвращаемый указатель) 2+2+4=8

; входные параметры пихаются в стек
mov ax, 2 ; b
push ax
mov ax, 1 ; a
push ax
sub SP, 8 ; резервируем место в стеке для возвращаемых значений

call func ; адрес возврата в стек, те SP = SP-4

mov ax, SS:[SP+0] ; результат функции в ptr
mov LOW(ptr),ax
mov ax, SS:[SP+2]
mov HIGH(ptr),ax

mov ax, SS:[SP+4] ; rb
mov rb, ax
mov ax, SS:[SP+6] ; ra
mov ra, ax

add SP, 8 ; возвращаем стек в исходное состояние

2. C'шный

void *func( int a, int b )


ptr = func( 1, 2);

при вызове
а) входные параметры в стек, начиная с первого
б) возвращаться может только одно значение и делается это через регистры al или ax или dx:ax

; входные параметры пихаются в стек
mov ax, 1 ; a
push ax
mov ax, 2 ; b

call func ; адрес возврата в стек, те SP = SP-4

mov LOW(ptr),ax
mov HIGH(ptr),ax
--------------------------------------------------------------------------------------------------




--------------------
Cpu not found ! Press any key for software emulation.
PM MAIL   Вверх
comcon1
Дата 22.6.2005, 19:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 838
Регистрация: 11.6.2005
Где: Москва ДАС-МГУ

Репутация: 12
Всего: 17



Хм. Не знал, что в Паскале и С разница такая. Я Паскальный, значить, описал. Ну да ладно - факт тот, что стек реанимируется, и ладно. smile
В репу б тебе поставил, да 100 нету smile


--------------------
PM MAIL   Вверх
vadims
Дата 22.6.2005, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 305
Регистрация: 8.6.2005

Репутация: 2
Всего: 17



Кстати, пока курил - осознал, что кое-что попутал - уж очень давно я библиотек на asm'е не писал.

1. Если речь о методе класса то передается еще указатель на объект

2. Похоже я попутал работу с возвращаемыми параметрами в паскалевском вызове. Вот теперь смутно припоминается что они не в стеке резервируются, а передаются через указатели

те

push <входные параметры>
push <адреса выходных параметров>
call func
add sp, <на сколько изменили указатель передаче параметров>

3. В С-шном вызове, помимо возврата BYTE,WORD,DWORD и указателя через dx.ax, можно ведь вернуть и структуру - в этом случае она точно резервируется в стеке перед вызовом функции (как я описывал работу с var аргументами в паскале)
и еще после call , обязательно надо восстановить стек прибавив к SP все то что мы использовали при передаче/резервировании, те
add SP, <size args>


Но основной вопрос ведь был, как и где распределяется память в зависимости от описания переменных и вызова функций - на него я ответил по моему корректно

Цитата(comcon1 @ 22.6.2005, 19:54)
В репу б тебе поставил, да 100 нету

Переведи, а что значит '100 нету' smile
Я как-то не очень владею этой феней




--------------------
Cpu not found ! Press any key for software emulation.
PM MAIL   Вверх
En_t_end
Дата 23.6.2005, 05:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2074
Регистрация: 4.12.2004

Репутация: 1
Всего: 20



Цитата
Переведи, а что значит '100 нету'
Я как-то не очень владею этой феней

Это означает, что у чела нет 100 сообщений, чтобы иметь право повышать тебе или понижать репутацию. ЗЫ не беспокойся, я тебе повысил smile
PM MAIL ICQ Skype GTalk Jabber   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1027 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.