Многоядерный в NASM Windows: данные lpParameter неверны при вводе - PullRequest
0 голосов
/ 03 марта 2019

У меня есть код в NASM (64 бит) в Windows для запуска четырех одновременных потоков (каждый из которых назначен отдельному ядру) на четырехъядерном компьютере с Windows x86-64.

Параметр lpParameter передается в r9 (переменные данных для каждого потока, передаваемого в функцию).Я передаю указатель на 8-элементный внутренний массив (ThreadInfo), который содержит переменные для включения в регистры при входе в функцию (переменные хранятся в регистрах в целях оптимизации).Все четыре потока вызывают одну и ту же функцию.

Проблема в том, что при входе в функцию все данные, передаваемые в массиве ThreadInfo, представляют собой большие (например, 128-битные) отрицательные числа.Массив содержит 64-битные целые числа.Массив доступен только для чтения для каждого из потоков, поэтому ни один поток не может изменить память.Я не понимаю, почему значения должны быть неправильными.Я проверил их в коде создания потока, и они верны, но они возвращают неправильные значения при чтении из вызываемой функции.

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

Init_Cores_fn:
; EACH OF THE CORES CALLS Test_Function AND EXECUTES THE WHOLE PROGRAM.  
; WE PASS THE STARTING BYTE (0, 8, 16, 24) AND THE "STRIDE" = NUMBER OF CORES.  
; ON RETURN, WE SYNCHRONIZE ANY DATA.  ON ENTRY TO EACH CORE, SET THE REGISTERS

; Populate the ThreadInfo array with vars to pass
; ThreadInfo: length, startbyte, stride, vars into registers on entry to each core
mov rdi,ThreadInfo
mov rax,ThreadInfoLength
mov [rdi],rax
mov rax,[stride]
mov [rdi+16],rax    ; 8 x number of cores (32 in this example)
; Register Vars
mov [rdi+24],r15
mov [rdi+32],r14
mov [rdi+40],r13
mov [rdi+48],r12
mov [rdi+56],r10

mov rbp,rsp ; preserve caller's stack frame
sub rsp,56 ; Shadow space

; _____

label_0:

mov rdi,ThreadInfo
mov rax,[FirstByte]
mov [rdi+8],rax ; 0, 8, 16, or 24

; _____
; Create Threads

mov rcx,0               ; lpThreadAttributes (Security Attributes)
mov rdx,0               ; dwStackSize
mov r8,Test_Function    ; lpStartAddress (function pointer)
mov r9,ThreadInfo       ; lpParameter (array of data passed to each core)

mov rax,0
mov [rsp+40],rax            ; use default creation flags
mov rax,[ThreadCount]
mov [rsp+32],rax            ; ThreadID

call CreateThread

; Move the handle into ThreadHandles array (returned in rax)
mov rdi,ThreadHandles
mov rcx,[FirstByte]
mov [rdi+rcx],rax

mov rax,[FirstByte]
add rax,8
mov [FirstByte],rax

mov rax,[ThreadCount]
add rax,1
mov [ThreadCount],rax

mov rbx,4
cmp rax,rbx
jl label_0

; _____
; Wait

mov rcx,rax         ; number of handles
mov rdx,ThreadHandles       ; pointer to handles array
mov r8,1                ; wait for all threads to complete
mov r9,1000         ; milliseconds to wait

call WaitForMultipleObjects

; _____

;[ Code HERE to do cleanup if needed after the four threads finish ]

mov rsp,rbp
jmp label_900

; __________________
; The function for all threads to call

Test_Function:

; Populate registers
mov rdi,r9
mov rax,[rdi]
mov r15,[rdi+24]
mov rax,[rdi+8] ; start byte
mov r13,[rdi+40]
mov r12,[rdi+48]
mov r10,[rdi+56]
xor r11,r11
xor r9,r9
pxor xmm15,xmm15
pxor xmm15,xmm14
pxor xmm15,xmm13

Указатель передается в r9, но при входе в Test_Function все значения являются большими (например, 128-битными) отрицательными значениями.Почему?

Спасибо за любую помощь в этом.

...