3.54
int decode2(int x, int y, int z)
{
z=z-y;
int k=z;
k<<=15;
k>>=15;
return k*(z^x);
}
3.56
A.哪个寄存器保存着程序值x、n、result和mask?
result—edi,mask—eax,x—esi,n–ebx
B.result和mask的初始值是什么?
result=1431655765=0x55555555
mask=2147483648=0x80000000
C.mask的测试条件是什么?
mask!=0
D.mask是如何被修改的?
mask>>=(n%0x10000)
E.result是如何被修改的?
result^=(mask & x)
F.填写这段C代码中所有缺失的部分。
1 int loop(int x, int n)
2 {
3 int result =0x55555555;
4 int mask;
5 for (mask =0x-80000000; mask!=0; mask =mask>>(n%0x10000)) {
6 result ^=(mask & x) ;
7 }
8 return result;
9 }
3.58
typedef enum {MODE_A, MODE_B, MODE_C, MODE_D, MODE_E} mode_t;
int switch3(int *p1, int *p2, mode_t action){
int result = 0;
switch(action){
case MODE_A:
result = *p1;
*p1 = *p2;
break;
case MODE_B:
result = *p1+*p2;
*p2 = result;
break;
case MODE_C:
*p2 = 15;
result = *p1;
break;
case MODE_D:
*p2 = *p1;
result=17;
break;
case MODE_E:
result = 17;
break;
default:
result = -1;
}
return result;
}
3.62
A. M 的值是多少?
19
B. 哪个寄存器保存着程序值 i 和 j?
ecx保存j,edi保存i
C. 重写 transpose 的一个 C 代码版本,使用在这个循环(上述汇编代码)中出现的优化思想。在你的代码中,使用参数 M,而不要用常数值。
void transpose(int A[M][M]){
int i,j;
for(i=0;i<M;i++){
int *temp1 = &A[i][0];
int *temp2 = &A[0][i];
for(j=0;j<i;j++){
int t = *temp1;
*temp1 = *temp2;
*temp2 = t;
temp1++;
temp2 += M;
}
}
}
3.65 在下面的代码中,A 和 B 是用#define 定义的常数:
GCC 为 setVal 的主体产生下面的代码:
1 movl 12(%ebp), %eax //eax=q;
2 movl 28(%eax), %edx //edx=(q+28)
3 addl 8(%eax), %edx //edx=(q+28)+*(q+8)
4 movl 8(%ebp), %eax //eax=p;
5 movl %edx, 44(%eax) p->y的地址是p+44
A 和 B 的值是多少?(答案是唯一的。)A=3,B=7
可列方程组
B=8; B+4+2B=28
AB2=44(没考虑对齐),A=11/4
然后考虑一下对齐原则,由于str2中含有int变量,所以其每个元素的地址都要是4的倍数,故B的实际值也有可能为7(为5,6时整型成员u可以前移4个存储单元)
然后将B=带入,得A=22/7,当取A=3时,AB*2=42,由于对齐原则,含有int型元素,要为4的倍数,故实际占有44个存储单元,验证通过,A=3,B=7即为唯一的答案。