《深入理解计算机系统》 练习题3.27-3.28 被调用者保存寄存器 栈指针

3.27

在这里插入图片描述
要求你将书中的阶乘函数,利用guarded-do的翻译策略,转换成c的goto版本,答案如上图。
注意第一次测试为if(n <= 1),这是因为,第一次测试实际是2 <= n,它的反面是2 > nn < 2n <= 1

3.28 反转x的二进制

在这里插入图片描述
题面上的汇编如上,在用汇编推理c语句时,对于for循环的测试条件,我刚开始没有想通,因为没有看见cmp指令。
原理:jne .L10是检测ZF标志位的,与它最近的语句subq $1, %rdx是有可能置ZF为1的,当%rdx为0时。

long fun_b(unsigned long x){
	long val = 0;
	long i;
	for(i = 64; i != 0; i--){
		val = (val << 1) | (x & 0x1);
		x >>= 1;
	}
	return val;
}

此函数用来获得x的二进制的反转。
x & 0x1获得当前x的第0位的数。val << 1将已经存储的二进制数移到更高一位上去。x >> 1既然当前x的第0位已经存储在了val,那么便丢弃掉第0位,右移1位,把第1位的数作为新的第0位的数。

3.7.5 寄存器中的局部存储空间

除了栈指针%rsp外,寄存器分为被调用者保存寄存器,和调用者保存寄存器。

在过程P调用Q时,如果值放在了被调用者保存寄存器中,那么它们的值在Q返回到P时,与P刚调用Q时,是一样的。Q如何保证这些值不变(要么不去碰它,要么暂时先放入栈帧中),对于P来说不用知道,因为对于P来说是透明的,P只需要在调用Q之前,将需要存储的值放入这些被调用者保存寄存器即可。
在这里插入图片描述
对于如上汇编代码,有三点需要注意:
1.两次push和两次pop。pushq %rbppushq %rbx先将寄存器中的值放入栈中,注意两个都是被调用者保存寄存器。也许你会觉得奇怪,第5和第8行已经按照要求,在调用Q之前把需要存储的值存入到了%rbp %rbx,为什么还要把%rbp %rbx的刚开始的值入栈存起来呢。

这是因为,刚开始的时候%rbp %rbx这两个寄存器可能就已经存了需要保存的值,但因为调用Q所以%rbp %rbx要暂时另作它用。换个角度说,当前的调用者P可能是别的过程的被调用者。这也就是原文中的“当然,要先把之前的值保存到栈上”这句话的意思。

2.为了存调用返回地址,需要手动分配栈空间。subq $8, %rsp这里分配的8字节栈空间,存了两次调用返回地址(分别是第8行和第11行的指令的地址),这里的8字节栈空间是被第二次利用了。

3.注意pushq %rbppushq %rbxsubq $8, %rsp的顺序,它们与后面第12、13、14行指令的顺序,这里是符合栈的先进后出的。

栈指针%rsp

阅读了这么多汇编代码后,总结下栈指针%rsp。
1.栈指针%rsp它其实不算是个寄存器,顾名思义,它是一个指针,指向当前栈顶地址。

2.比如%rax,它一个普通的寄存器,取%rax时,就会取它装有的8字节数据,可能它是个指针;取(%rax)时,则成了内存引用,会取出这个指针指向的数据;
%rsp,它是栈指针,取%rsp时,返回的是当前栈指针的地址形如0x7fffffffe820;取(%rsp)时,则可能取出从820-827这8个字节里面存的数据;而一般来说,我们不需要取%rsp,因为要栈顶地址来根本没用啊。

指针的理解

数据在计算机中是一个一个字节存的,而每个字节都有一个序号,我们称这些字节序号为地址,或指针。
这个序号的表示范围为8个字节的表示范围,8*8=64,即可以用64二进制来表示一个地址。按照无符号数来说,这个序号的范围是0 ~ 26412^{64}-1。由于一个十六进制数可以表示4位二进制,而一个字节是8位二进制,所以一个字节的值可以用两个十六进制数来表示,而地址可以用16个十六进制数来表示。

movq (%rdi), %rax为例,假设8字节寄存器%rdi存的是一个指针,即字节序号,这里假设为A。(%rdi)为内存引用,配合movq(q为四字,8字节),这条指令就会取A,A+1,A+2…A+6,A+7这8个字节存的数据,再放到%rax这个8字节寄存器中(取的是8字节的数据,容器的量也是8字节,肯定没有问题)。

接上一条指令,movq %rax, (%rsi),首先会取出8字节的数据来,假设%rsi寄存器存的是一个指针,地址为B,配合movq(q为四字,8字节),这条指令会取出的8个字节的数据,分别放到B,B+1,B+2…B+6,B+7这8个字节中。

注意内存引用时,括号内的寄存器必为8字节寄存器,且这8个字节存的是一个指针。

posted @ 2018-11-25 19:23  allMayMight  阅读(182)  评论(0编辑  收藏  举报