Да, как? Друзья! Приветствую всех! Допустим, я хочу сохранить в локальной памяти потока значения регистро ESI и EDI. Тогда использую код Код (Text): ;запихиваю локальную память потока значения ESI и EDI call TlsAlloc ;Пусть TlsAlloc вернула значение x push ESI push EAX call TlsSetValue call TlsAlloc push EDI push EAX call TlsSetValue ;...некоторый код... ;а теперь достаю из локальной памяти потока положенные туда значения. Освободившиеся ячейки памяти ;(номера x и x+ 1) можно будет использовать по-новой call TlsAlloc sub eax, 2 push EAX call TlsGetValue ;cейчас в EAX сохранённое значение ESI call TlsAlloc sub eax, 2 push EAX call TlsGetValue ;cейчас в EAX сохранённое значение EDI ;Теперь посмотрим на значение свободной ячейки call TlsAlloc ;это значение равно x+ 4! Вот, собственно, вопрос и заключается в том, как сделать, чтобы следующий вызов Код (Text): call TlsAlloc Давал значение x, а не x+ 4. ... Функция TlsFree? Не подоходит. Ведь читаем у Джефри Рихтера (глава 21) "Когда необходимость в TLS-области у всех потоков в процессе отпадет, вызовите TlsFree" В других источниках тоже говорится о целесообразности вызова TlsFree, если отпадает надобность TLS-области у ВСЕХ потоков. А у меня только у одного потока такая надобность отпадает Помогите, пожалуйста!
Каждый вызов TlsAlloc быдет возвращать адрес новой ячейки, потому-что эта функция пердназначена для того, чтобы резервировать новую ячейку. Зачем резервировать одну и ту же ячейку дважды?
Угу. Теперь вопрос: Я считал с некоторой ячейки значение x. Теперь я хочу положить в эту ячейку некоторое значение. Как?
Также как ты до этого делал, с помощью TlsSetValue http://www.wasm.ru/article.php?article=tls http://msdn.microsoft.com/en-us/library/ms686818(VS.85).aspx
В общем, быстрый пример: Код (Text): Глобальная инициализация, выполнять _только_ один раз: call TlsAlloc mov [g_index1], eax call TlsAlloc mov [g_index2], eax Теперь в любом потоке можно использовать аллоцированные индексы (т.е. индексы глобальны для процесса, а значения, получаемые\выставляемые по этим индексам — локальны (уникальны) для каждого потока): push esi ; сохраним esi push [g_index1] call TlsSetValue push 0xcafebabe ; сохраним что-нибудь другое под другим индексом push [g_index2] call TlsSetValue ... push [g_index1] call TlsGetValue Глобальная деинициальизация: push [g_index1] call TlsFree push [g_index2] call TlsFree Вот так не делай так ни в коем случае (ведь формально один не может заранее знать, что ему вернёт TlsAlloc): Код (Text): call TlsAlloc sub eax, 2 Ничего не поделаешь здесь. Максимум — можно обнулить значение локальной переменной: Код (Text): push 0 push [g_index1] call TlsSetValue
Спасибо. Просто я такой вот код Код (Text): call TlsAlloc mov [g_index1], eax в находимых мною примерах игнорировал. (И в своём коде не использовал ячейки памяти, только регистры.) Ибо рассуждал, что g_index1 находится в адресном пространстве всего процесса. Один поток положил туда значение, второй положил... И что же? Для одного потока [g_index1]== a, а для другого [g_index1]== b? Очень, знаете, ли странно. Впрочем, нет ни малейшего основния этому не верить. Тем более, после разъяснений. Надо пробовать
Не получилось у нас однозначно распознать последний пост... Так что на всякий случай подтвердим: Да, g_index1 в адресном пространстве процесса; магия не используется: для одного потока [g_index1]==a, для другого [g_index1]==a, для третьего же [g_index1]==a. [И это из-за того, что код 'g_index1 := TlsAlloc()' нужно выполнять только один раз — например, сразу после старта программы, до создания других потоков (или, во всяком случае, до того, как какой-либо поток вызовет TlsSetValue\TlsGetValue)].
Опять ничего не понял Чуть пониже ...Так значения по этим индексам уникальны для каждого потока или всё же для всех потоков одинаковы?
Отличная вышла путаница, разве нет? Переформулируем: Допустим, есть у нас 3 потока. Вызываем TlsAlloc (из любого одного потока) и получаем индекс == 0xaa. После этого из потока1 вызываем TlsSetValue(0xaa, 0x11), а из потока2 — TlsSetValue(0xaa, 0x22). Теперь смотрим, что вернёт TlsGetValue: поток1: TlsGetValue(0xaa) == 0x11 поток2: TlsGetValue(0xaa) == 0x22 поток3: TlsGetValue(0xaa) == 0 ; Начальное значение — ноль.
Ну, я так первоначально и понял. Спасибо. Пошёл ковыряться. ...Я ведь не приложение пишу, а api-функцию перехватываю. Там сложно всё!