第二十六章
第一题
我们首先阅读loop.s这个简单的程序,这里我们选择使用cat loop.s:
.main
.top
sub $1,%dx
test $0,%dx
jgte .top
halt
通过阅读相应的代码,我们知道这里将寄存器dx将其减1之后,使用test命令,之后判断dx是否大于等于0,决定是否跳转到top,若不满足则执行halt指令。
接下来,输入指令:./x86.py -p loop.s -t 1 -i 100 -R dx
刚开始的时候dx为0,执行完第一行指令之后,dx的值变为-1,所以接下来的判断没有成立,所有指令顺序执行到halt指令。
接下来,使用-c指令来检查一下我的答案:
经过验证,可以知道答案是正确的。
第二题
现在运行指令./x86.py -p loop.s -t 2 -i 100 -a dx=3, dx=3 -R dx
这里,dx的初始值为3,每次循环dx会减1,直到dx的值为负值,进程0停止执行,开始执行进程1,进程1的dx的初始值也为3,所有也会循环执行dx–直到dx的值为负值,进程1也停止执行。分析的结果就是由于是每100条指令产生一个中断,在中断之前,进程就已经停止执行了,所有多个线程的存在并不会影响计算,这段代码没有竞态条件。
下面是-c的答案:
可以看出,我们的分析是正确的。由于程序在操作系统中断之前完成,所以多个线程的存在没有影响计算,代码没有竞争条件。
第三题
输入指令:./x86.py -p loop.s -t 2 -i 3 -R dx -a dx=3,dx=3 -r -c -s 1查看种子为1时的结果为:
输入指令:./x86.py -p loop.s -t 2 -i 3 -R dx -a dx=3,dx=3 -r -c -s 2查看种子为2时的结果为:
输入指令:./x86.py -p loop.s -t 2 -i 3 -R dx -a dx=3,dx=3 -r -c -s 3查看种子为3时的结果为:
首先,我们发现两个进程并不共享变量,也就是不存在临界区,也就是中断频率并不会影响每个进程进行循环的次数,以及什么时候执行halt指令,都是确定的。但是整个程序,进程0和进程1之间的中断顺序和中断之间相关时间会发生改变。
第四题
首先输入指令:cat looping-race-nolock.s,观察代码为:
# assumes %bx has loop count in it
.main
.top
# critical section
mov 2000, %ax # get 'value' at address 2000
add $1, %ax # increment it
mov %ax, 2000 # store it back
# see if we're still looping
sub $1, %bx
test $0, %bx
jgt .top
halt
由代码可以知道程序的功能:首先将内存地址2000中的值赋给寄存器%ax,然后将寄存器%ax中的值加1,再将寄存器%ax中的值重新写回内存地址2000中,最后根据寄存%bx中的值执行以上循环(这里未设置,默认bx为0,执行一次)。由此得到程序单线程运行情况。
接下来,输入指令:./x86.py -p looping-race-nolock.s -t 1 -M 2000 -c时我们可以看到结果为:
发现,寄存器ax里面的值是根据dx的值来加1的,与我们的分析是一致的。