我正在Windows中用NASM(64位)编写代码,以便在四核Windows x86-64机器上同时运行四个线程(每个线程分配给一个单独的核心)。下面是我的线程实例化代码。每个线程调用相同的程序。
代码如下所示,其显示顺序与源文件中的显示顺序完全相同(没有.data部分,有些代码缩写)。每个线程(核心)在一个大数组中执行Test_函数。第一个核心从数据元素0开始,第二个核心从1开始,第三个核心从2开始,第四个核心从3开始,每个核心递增4(例如,0、4、8、12)。完成后,Test_函数在标签_899处退出。它们将结果写入使用malloc创建的共享数组中的相应位置。
我的问题是:在标签_899上完成所有线程后,我要去哪里?然后线程是否返回到执行清理的ThreadStart的最后一行(jl label_0之后)?Test_函数随ret一起退出,所以我假设它将控制权返回到线程实例化部分(ThreadStart)。
不幸的是,我读到的所有信息都集中在创建一个线程上。一些参考资料讨论了运行时的线程同步,但我没有发现任何与所有线程完成后发生的事情直接相关的内容。
谢谢你的帮助。我会发布一个完整的例子,但我还不知道如何完成它,这是我的问题。
ThreadStart:
mov rbp,rsp ; preserve caller's stack frame
mov rdi,ThreadInfo ; two element array
sub rsp,32 ; Shadow space
label_0:
mov rax,StartByte
mov [rdi],rax ; 0, 8, 16, or 24
mov rax,[JumpCount]
mov [rdi+8],rax ; number of cores (4 in this example)
push 0 ; Creation flags, start immediately (may want to delay until all created)
push 0 ; ThreadID
mov rcx,0 ; lpThreadAttributes (Security Attributes)
mov rdx,0 ; dwStackSize
mov r8,Test_Function ; lpStartAddress (function pointer)
mov r9,rdi ; lpParameter
call CreateThread
mov rax,8
add [StartByte],rax
mov rax,[TreadCount]
add rax,1
mov [TreadCount],rax
cmp rax,4
jl label_0
[ Code to do cleanup if needed after the four threads finish ]
mov rsp,rbp
jmp final_out
;______
Test_Function:
xor rcx,rcx
mov [loop_counter_401],rcx
label_401:
lea rdi,[rel numbers_ptr]
mov rbp,qword [rdi] ; Pointer
mov rcx,[loop_counter_401]
mov rax,[numbers_length]
cmp rcx,rax
jge label_899
movsd xmm0,qword[rbp+rcx]
movsd [num_float],xmm0
add rcx,32 ;8 -- add 32 for four loops, not 8
mov [loop_counter_401],rcx
[ MORE CODE]
jmp label_401
label_899:
ret
;______
final_out:
mov rdi,Return_Pointer_Array
mov rax,r15
mov [rdi+0],rax
mov rax,r14
mov [rdi+8],rax
mov rax,rdi
ret
更新030119
下面是创建线程的代码。早些时候,我认为它在CreateThread失败,但事实并非如此。由于我调用的代码有问题,它现在失败了,我正在调试它。我会发回我的结果。失败可能在于我如何编写WaitForMultipleObjects的代码。
显示的是线程实例化代码,而不是线程调用的代码。
mov rdi,ThreadInfo
mov rax,StartByte
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 rax,rdi
mov r9,rax ; 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,[StartByte]
mov [rdi+rcx],rax
mov rax,8
add [StartByte],rax
mov rax,[ThreadCount]
add rax,1
mov [ThreadCount],rax
cmp rax,4
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 to do cleanup if needed after the four threads finish ]
mov rsp,rbp
jmp label_900