问题
I have code in NASM (64 bit) in Windows to run four simultaneous threads (each assigned to a separate core) on a four-core Windows x86-64 machine.
The lpParameter is passed in r9 (the data variables for each thread to pass to the function). I am passing a pointer to an 8-element internal array (ThreadInfo) which contains variables to put into registers on entry to the function (variables are stored in registers for optimization purposes). All four threads call the same function.
The problem is that on entry to the function, the data passed in the ThreadInfo array are all large (e.g. 128-bit) negative numbers. The array contains 64-bit integers. The array is read-only for each of the threads, so no thread can alter the memory. I don't understand why the values should be wrong. I tested them in the thread creation code and they are correct, but they return incorrect values when read from the called function.
Here is the test code showing the relevant parts. Showing a reproducible example may not be possible due to the register values, but if this question can't be answered without that, then I can see if it's feasible to post a completely reproducible program.
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
The pointer is passed in r9, but on entry to Test_Function, the values are all large (e.g., 128-bit) negative values. Why?
Thanks for any help on this.
来源:https://stackoverflow.com/questions/54963179/multicore-in-nasm-windows-lpparameter-data-are-wrong-on-entry