首页 > 编程语言 >10.13了解程序运行方式的必要性

10.13了解程序运行方式的必要性

时间:2023-02-07 20:55:17浏览次数:39  
标签:函数 程序运行 汇编语言 counter 必要性 数值 MyFunc2 10.13 源代码

通过对 C语言源代码和汇编语言源代码进行比较,想必大家对程序是怎样跑起来的”又有了更深的理解。而且,从汇编语言源代码中获得的知识,在某些情况下对查找 bug 的原因也是有帮助的。

让我们来看个示例。代码清单 10-13 是更新全局变量 counter 的值的C语言程序。MyFunc1 函数和MyFunc2函数的处理内容,都是把全局变量 counter的值放大到2倍。counter *= 2;指的是把counter 的数值乘以2,然后再把所得结果赋值到 counter 的意思。这里,假设我们利用多线程处理 同时调用了一次 MyFunc 函数和MyFunc2函数。这时,全局变量 counter 的数值,理应变成 100x2x2=400。然而,某此时候结果也可能会是 200。至于为什么会出现该 bug,如果没有调查过汇编语言的源代码,也就是说如果对程序的实际运行方式不了解的话是很难找到其原因的。

 

 将代码清单 10-13的 counter *= 2;部分转换成汇编语言源代码后结果就如代码清单 10-14 所示。这里希望大家注意的是,C 语言源代码中 counter *= 2; 这一个指令的部分,在汇编语言源代码,也就是实际运行的程序中,分成了3 个指令。如果只是看 counter *= 2; 的话,就会以为 counter 的数值被直接扩大为了原来的 2倍。然而,实际上执行的却是“把 counter的数值读入eax 寄存器”“将eax寄存器的数值变成原来的2倍”“把eax 寄存器的数值写人 counter”这3个处理。

 

 在多线程处理中,用汇编语言记述的代码每运行1行,处理都有可能切换到其他线程(函数)中。因而,假设 MyFuncl 函数在读出counter的数值 100后,还未来得及将它的2倍值200写入counter 时正巧MyFunc2函数读出了counter 的数值100,那么结果就会导致counter 的数值变成了 200(图10-8)。

 

 为了避免该 bug,我们可以采用以函数或 C 语言源代码的行为单位来禁止线程切换的锁定方法。通过锁定,在特定范围内的处理完成之前,处理不会被切换到其他函数中。至于为什么要锁定 MyFunc1 函数和 MyFunc2 函数,大家如果不了解汇编语言源代码的话想必是不明白的吧。

标签:函数,程序运行,汇编语言,counter,必要性,数值,MyFunc2,10.13,源代码
From: https://www.cnblogs.com/z1218/p/17099787.html

相关文章