VB.NET并行与分布式编程(4)-线程栈[1]
1、用调试器调试线程
?1)栈调用
以下面代码为例
Imports System.ThreadingPublic Class Form1 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click Dim main_x As Integer main_x = 5 Call sub1(main_x) End Sub Private Sub sub1(sub1_x As Integer) Dim jg As Integer jg = sub1_x * sub1_x Call sub2(jg) End Sub Private Sub sub2(sub2_x As Integer) Dim jg As Integer jg = sub2_x * 2 '在下一句设置断点 jg = jg * jg End SubEnd Class
?
?
?
?
?
?我们首先来看调用堆栈,在调试菜单中选择调用堆栈,可看到过程的调用顺序:
?然后查看线程
?最后查看局部变量
?此外,我们还可以研究一下这个线程的调用时堆栈情况,通过反汇编代码,在调用堆栈窗口中选择“转到反汇编”
?
Private Sub sub2(sub2_x As Integer)00000000 push ebp 00000001 mov ebp,esp 00000003 sub esp,14h 00000006 mov dword ptr [ebp-10h],ecx 00000009 mov dword ptr [ebp-4],edx 0000000c cmp dword ptr ds:[0256B1B8h],0 00000013 je 0000001A 00000015 call 62A16743 0000001a xor edx,edx 0000001c mov dword ptr [ebp-8],edx 0000001f mov eax,dword ptr [ebp-10h] 00000022 mov dword ptr [ebp-14h],eax 00000025 mov ecx,dword ptr [ebp-10h] 00000028 call 628F5C25 0000002d mov dword ptr [ebp-0Ch],eax 00000030 push 32h 00000032 mov edx,dword ptr [ebp-0Ch] 00000035 mov ecx,dword ptr [ebp-14h] 00000038 call FFDF30D0 0000003d mov ecx,dword ptr [ebp-4] 00000040 call FFFFFF70 00000045 mov ecx,63h 0000004a call FFDF2940 0000004f nop Dim jg As Integer jg = sub2_x * 200000050 mov eax,dword ptr [ebp-4] 00000053 mov edx,2 00000058 imul eax,eax,2 0000005b jno 00000062 0000005d call 62A19A30 00000062 mov dword ptr [ebp-8],eax '在下一句设置断点 jg = jg * jg00000065 mov eax,dword ptr [ebp-8] 00000068 imul eax,dword ptr [ebp-8] 0000006c jno 00000073 0000006e call 62A19A30 00000073 mov dword ptr [ebp-8],eax End Sub00000076 nop 00000077 nop 00000078 mov ecx,63h 0000007d call FFDF2A60 00000082 nop 00000083 mov esp,ebp 00000085 pop ebp 00000086 ret
?
?
ESP是栈顶指针
ebp是基址指针
+-----+
+基址 +
+-----+
+栈内容+
+栈内容+
?
+栈内容+
+栈内容+
+栈内容+
?
+栈顶?? +
如上图所示,基地的地址比栈顶的地址大,就是向下增长。
寄存器ebp和esp保存着当前的基址和栈顶地址
首先,进入函数时
00000000? push??????? ebp
备份基址指针
00000001? mov???????? ebp,esp
然后设置基址指针指向栈顶,相当于为当前栈清空了内容,做好在栈中分配局部变量的准备
00000003? sub???????? esp,14h
完成栈(可以理解为本函数可访问的栈)的空间分配,将栈顶指针向下增长14h(向下增长的意思是栈的空间增长规律是地址递减)。相当于栈中已经容纳了14h的空间
?
??????? Dim jg As Integer
??????? jg = sub2_x * 2
00000050? mov???????? eax,dword ptr [ebp-4]
00000053? mov???????? edx,2
00000058? imul??????? eax,eax,2
0000005b? jno???????? 00000062
0000005d? call??????? 617391D0
00000062? mov???????? dword ptr [ebp-8],eax
??????? '在下一句设置断点
??????? jg = jg * jg
00000065? mov???????? eax,dword ptr [ebp-8]
00000068? imul??????? eax,dword ptr [ebp-8]
0000006c? jno???????? 00000073
0000006e? call??????? 617391D0
00000073? mov???????? dword ptr [ebp-8],eax
?
从上面这段代码可以看出来
sub2_x分配在了dword ptr [ebp-4] ,而jg分配在了dword ptr [ebp-8]
?
最后,离开函数时,恢复进入函数前栈的指针,相当于释放了本次在栈中分配的空间
??? End Sub
00000083? mov???????? esp,ebp
恢复栈顶指针
00000085? pop???????? ebp
恢复基址指针
00000086? ret
?
2、修改默认栈的大小
???????? Dim?线程变量名 As Thread = New Thread(函数名,以字节为单位的栈大小)
比如
??????? Dim mythread As Thread = New Thread(myfun,1024*512)
分配了512kb字节
?