CASPP 第三章课后习题解答
3.58
一个函数的原型为
1
|
long decode2(long x, long y, long z);
|
GCC产生的汇编代码为
1
2
3
4
5
6
7
|
decode2:
subq %rdx, %rsi
imulq %rsi, %rdi
movq %rsi, %rax
salq $63, %rax
sarq $63, %rax
xorq %rdi, %rax
|
参数x、y、z通过寄存器%rdi、%rsi和%rdx传递。代码将返回值存放在寄存器%rax中。写出等价于上述汇编代码的C代码。
1
2
3
4
5
6
7
8
|
int decode(int x, int y, int z)
{
y = y - z;
x = x * y;
int res = y << 63;
res >>= 63;
return res ^ x;
}
|
这里可以使用将汇编代码进行编译连接,产生方法嵌入到可执行文件中。
1
2
|
gcc -c -m64 decode2.s -o decode2.o
gcc -m64 main.c decode.c decode2.o -o main
|
3.60
请解释下面汇编代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
loop:
movl %esi, %ecx
movl $1, %edx
movl $0, %eax
jmp .L2
.L3:
movq %rdi, %r8
andq %rdx, %r8
orq %r8, %rax
salq %cl, %rdx
.L2:
testq %rdx, %rdx
jne .L3
rep
ret
|
将其转换为C语言(涉及的知识有)
1
2
3
4
5
6
7
8
9
10
|
long loop2(long x, int n)
{
long res = 0;
long mask;
for (mask = 1; mask !=0 ; mask=mask<<n)
{
res |= x & mask;
}
return res;
}
|
3.61
查看代码
1
2
3
4
5
6
7
8
|
// 试图读取空地址的值
long cread(long *xp) {
return (xp ? *xp : 0);
}
long cread_alt(long *xp) {
return (!xp ? 0 : *xp);
}
|
使用条件传送指令(CSAPP 147页)
1
2
3
4
|
cread_alt:
movl $0, %eax
testq %rdi, %rdi
cmovne (%rdi), %rax
|
3.62
3.63
3.64