Использование памяти стека
От: maks1180  
Дата: 31.10.22 23:24
Оценка:
Можно ли такое реализовать на с/с++, без ассемблерных вставок ?
Есть ли какие-нибудь расшерения с/с++, что-бы такое делать ?

1. функция funcA вызывает funcB.
2. функция funcB, решает сколько ей нужно памяти, выделяет её в стеке и заполняет данными и возвращает указатель на выделенную память.
3. сразу после возврата из funcB, мы сдвигаем регистр ESP(RSP), что-бы следующие вызовы не порушили эту память. Теперь внутри funcA мы можем безопастно использовать память выделенную в стеке funcB.
===============================================
(реклама, удалена модератором)
Re: Использование памяти стека
От: koenjihyakkei Россия  
Дата: 31.10.22 23:35
Оценка: +3
Здравствуйте, maks1180, Вы писали:

alloca
Re: Использование памяти стека
От: VladFein США  
Дата: 31.10.22 23:43
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Можно ли такое реализовать на с/с++, без ассемблерных вставок ?


Скорее всего — нет. К тому же, Вы получите ВЕСЬ стек funcB.

Я бы выделил функцию, возвращающую нужный размер, и звал alloca по-честному из funcA
Re[2]: Использование памяти стека
От: maks1180  
Дата: 31.10.22 23:53
Оценка:
VF>Скорее всего — нет. К тому же, Вы получите ВЕСЬ стек funcB.
Да, получу весь стек, это же не страшно.
А если в funcA снова вызвать alloca, что-бы зарезервировать эту память. По сути alloca это и есть (sub rsp,ххх)

VF>Я бы выделил функцию, возвращающую нужный размер, и звал alloca по-честному из funcA


Например funcB это sprintf, она пасит шаблон (перевод числа в строки) считает сколько нужно памяти для конечной строки, выделяет память и если её тут прервать, то нужно будет парсить заново!
Этого хочу избежать.
===============================================
(реклама, удалена модератором)
Re: Использование памяти стека
От: · Великобритания  
Дата: 31.10.22 23:55
Оценка:
Здравствуйте, maks1180, Вы писали:

m> Можно ли такое реализовать на с/с++, без ассемблерных вставок ?

m> Есть ли какие-нибудь расшерения с/с++, что-бы такое делать ?
m> 1. функция funcA вызывает funcB.
m> 2. функция funcB, решает сколько ей нужно памяти, выделяет её в стеке и заполняет данными и возвращает указатель на выделенную память.
m> 3. сразу после возврата из funcB, мы сдвигаем регистр ESP(RSP), что-бы следующие вызовы не порушили эту память. Теперь внутри funcA мы можем безопастно использовать память выделенную в стеке funcB.
Как освобождать стек funcB?
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[2]: Использование памяти стека
От: maks1180  
Дата: 01.11.22 00:17
Оценка:
m>> 3. сразу после возврата из funcB, мы сдвигаем регистр ESP(RSP), что-бы следующие вызовы не порушили эту память. Теперь внутри funcA мы можем безопастно использовать память выделенную в стеке funcB.
·>Как освобождать стек funcB?

Либо обратно сдвинуть ESP(RSP) либо после выхода из funcA она автоматически освободиться.
===============================================
(реклама, удалена модератором)
Re: Использование памяти стека
От: Mr.Delphist  
Дата: 01.11.22 11:23
Оценка:
Здравствуйте, maks1180, Вы писали:

M>1. функция funcA вызывает funcB.

M>2. функция funcB, решает сколько ей нужно памяти, выделяет её в стеке и заполняет данными и возвращает указатель на выделенную память.

А почему именно стек? Исходя из описанного сценария, heap подойдёт не хуже, плюс не нужны танцы с бубном, и нет возможности испортить/атаковать стек.
Re: Использование памяти стека
От: koenjihyakkei Россия  
Дата: 01.11.22 12:11
Оценка:
Здравствуйте, maks1180, Вы писали:


Если так хочется использовать стек вместо хипа, то можно использовать стек на хипе. Единственное что его придется делать глобальным или передавать в функции. Хотя в кланге и гцц все же можно выделить отдельный регистр для этого.

Но управлять нативным стеком без жестких плясок с ассемблером вряд ли получится.
Re[2]: Использование памяти стека
От: maks1180  
Дата: 01.11.22 12:34
Оценка:
MD>А почему именно стек? Исходя из описанного сценария, heap подойдёт не хуже, плюс не нужны танцы с бубном, и нет возможности испортить/атаковать стек.

выделение в heap медленнее значительно!
===============================================
(реклама, удалена модератором)
Re[3]: Использование памяти стека
От: · Великобритания  
Дата: 01.11.22 13:19
Оценка:
Здравствуйте, maks1180, Вы писали:

m>>> 3. сразу после возврата из funcB, мы сдвигаем регистр ESP(RSP), что-бы следующие вызовы не порушили эту память. Теперь внутри funcA мы можем безопастно использовать память выделенную в стеке funcB.

M>·>Как освобождать стек funcB?
M>Либо обратно сдвинуть ESP(RSP) либо после выхода
Так ты тогда и обратно сдвинешь эту твою выделенную память в стеке.
Ведь стек funcB будет выделен раньше, значит удалить фрагмент в серединке стека у тебя не выйдет.

M>из funcA она автоматически освободиться.

А если funcB будет вызываться много раз? В цикле?

Главное я не понимаю — а зачем? Вроде ты говоришь, что "выделим на стеке быстро, чтобы потом скинуть в файл". Зачем тогда вообще что-то выделять, когда можно сразу в файл кидать?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: Использование памяти стека
От: kov_serg Россия  
Дата: 01.11.22 14:44
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Можно ли такое реализовать на с/с++, без ассемблерных вставок ?

M>Есть ли какие-нибудь расшерения с/с++, что-бы такое делать ?

M>1. функция funcA вызывает funcB.

M>2. функция funcB, решает сколько ей нужно памяти, выделяет её в стеке и заполняет данными и возвращает указатель на выделенную память.
M>3. сразу после возврата из funcB, мы сдвигаем регистр ESP(RSP), что-бы следующие вызовы не порушили эту память. Теперь внутри funcA мы можем безопастно использовать память выделенную в стеке funcB.

Типа такого?
#include <functional>

void funcB(std::function<void(char*)> cb) {
    int size=10+rand()%100; // deside
    char buf[size]; // allocate
    buf[0]=size&255; for(int i=1;i<size;i++) buf[i]=i&15; // prepare data
    cb(buf);
}

void funcA() {
    // code
    funcB([](char* buf){
        // code
    });
    // code
}
Re[2]: Использование памяти стека
От: maks1180  
Дата: 01.11.22 15:03
Оценка:
Спасибо! Это что-то новое для меня... Это в каком стандарте это появилось ?
Получается funcB вызывает функцию cb по ссылке или funcB завершается и потом уже funcA работает со стеком который остался от funcB ?
===============================================
(реклама, удалена модератором)
Re[3]: Использование памяти стека
От: σ  
Дата: 01.11.22 17:25
Оценка:
M>Спасибо! Это что-то новое для меня... Это в каком стандарте это появилось ?

Ни в каком не появилось, этот жирный тролль использовал GCC-шное расширение для VLA.

M>Получается funcB вызывает функцию cb по ссылке или funcB завершается и потом уже funcA работает со стеком который остался от funcB ?


Первое.
Отредактировано 01.11.2022 17:38 σ . Предыдущая версия .
Re[3]: Использование памяти стека
От: maks1180  
Дата: 01.11.22 17:49
Оценка:
M>Спасибо! Это что-то новое для меня... Это в каком стандарте это появилось ?
M>Получается funcB вызывает функцию cb по ссылке или funcB завершается и потом уже funcA работает со стеком который остался от funcB ?

Посмотрел я код, который компилиет gcc 10.2. Он отдельно создал функцию (funcA()::{lambda(char*)#1}>} и её вызывает funcB. Соответсвенно лямда функция не может обращаться к переменным функции funcA. Ничего нового это не даёт, тоже самое если создать 3-ю функцию и её адрес передать в funcB.

Нужно было другое, работать в funcA со стеком, который остался от funcB после её завершения.
===============================================
(реклама, удалена модератором)
Re[4]: Использование памяти стека
От: · Великобритания  
Дата: 01.11.22 19:43
Оценка:
Здравствуйте, maks1180, Вы писали:

m> M>Спасибо! Это что-то новое для меня... Это в каком стандарте это появилось ?

m> M>Получается funcB вызывает функцию cb по ссылке или funcB завершается и потом уже funcA работает со стеком который остался от funcB ?

m> Соответсвенно лямда функция не может обращаться к переменным функции funcA.

Почему не может? Есть же google: c++ lambda capture by reference
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[5]: Использование памяти стека
От: maks1180  
Дата: 01.11.22 20:46
Оценка:
m>> Соответсвенно лямда функция не может обращаться к переменным функции funcA.
·>Почему не может? Есть же google: c++ lambda capture by reference

Как вообще функция, может обращаться к переменным другой функции ?
===============================================
(реклама, удалена модератором)
Re[6]: Использование памяти стека
От: · Великобритания  
Дата: 01.11.22 20:47
Оценка:
Здравствуйте, maks1180, Вы писали:

m>>> Соответсвенно лямда функция не может обращаться к переменным функции funcA.

M>·>Почему не может? Есть же google: c++ lambda capture by reference
M>Как вообще функция, может обращаться к переменным другой функции ?
по ссылке. ты в гугл-то ходил?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[6]: Использование памяти стека
От: kov_serg Россия  
Дата: 02.11.22 06:55
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Как вообще функция, может обращаться к переменным другой функции ?

А в чем проблема?
#include <functional>

struct funcB_vars {
    int x,y;
};
void funcB(std::function<void (funcB_vars*)> cb) {
    funcB_vars vars[1];
    vars->x=1;
    vars->y=1;
    cb(vars);
}
int funcA(int x,int y) {
    if (x<0) x=0;
    if (y<0) y=-y;
    int r=0;
    funcB([&](funcB_vars *vars){
        vars->x=x;
        vars->y+=y;
        r=vars->x+vars->y;
    });
    r*=r;
    return r;
}
Re[3]: Использование памяти стека
От: Mr.Delphist  
Дата: 02.11.22 07:23
Оценка:
Здравствуйте, maks1180, Вы писали:

M>выделение в heap медленнее значительно!


Хинт: менеджеры памяти бывают разные, в том числе с Prealloc, и без thread safety блокировок — "значительности" не будет.
Re[4]: Использование памяти стека
От: rg45 СССР  
Дата: 02.11.22 08:38
Оценка: :)
Здравствуйте, σ, Вы писали:

M>>Спасибо! Это что-то новое для меня... Это в каком стандарте это появилось ?


σ>Ни в каком не появилось, этот жирный тролль использовал GCC-шное расширение для VLA.


Человек открыл для себя лямбда выражения, а ты ему про какие-то расширения.
--
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.