Общая память между потоками на уровне сборки

#multithreading #assembly #nasm #shared-memory

#многопоточность #сборка #nasm #разделяемая память

Вопрос:

Итак, у меня есть программа на C, которая создает потоки с использованием библиотеки pthread и вызывает функцию, написанную на ассемблере.

Мой вопрос: как я могу получить общую память между потоками, которые запускают ассемблерный код?

Я знаю, что могу передать указатель

 typedef struct{
    int *value;
    } t_data;

static int global_value = 0;

int main(){
    t_data td;
    td.value = amp;global_value
    //creating threads in loop or something with id declared
    pthread_create(id, NULL, amp;assembly_foo, (void*)amp;td)
    assembly_foo((void*)amp;td)
    //joining threads
}
  

таким образом, на уровне сборки оба потока могут увеличивать значение global_value:

 global assembly_foo

section .text

assembly_foo:
    mov rsi, [rdi]
    lock inc dword[rsi]
    ret
  

Дело в том, что я хочу сделать что-то похожее, но без передачи какого-либо аргумента.
Насколько я знаю, регистры и стек различны для каждого потока.
Мне не нужно это значение в C позже, мне просто нужно немного (константа времени компиляции) общих байтов для реализации какого-то типа блокировки / мьютекса, чтобы я мог синхронизировать потоки.

Комментарии:

1. Потоки совместно используют все свое виртуальное адресное пространство; статическое хранение в .bss или .data — самый простой способ, или вы можете передать указатель в качестве аргумента в функцию инициализации потока.

2. итак, если, например, я ранее объявил « .bss shared_data resb 4096 « и у меня есть 50 потоков, выполняющих эту функцию, она займет всего 4 КБ и будет разделена между всеми 50 потоками?

3. Да, точно так же, как в C, если у вас есть несколько потоков, обращающихся напрямую к одной и той же глобальной переменной. Они буквально компилируются в asm, который просто делает это.

4. Каждый байт в памяти, доступный данному потоку, также доступен по тому же адресу любому другому потоку в том же процессе.

5. @rcgldr Хотя базовое значение для FS / GS изменяется для каждого потока, они по-прежнему указывают на то же виртуальное адресное пространство, которое используют другие сегментные регистры.