答案均由本人完成,并且實驗或者調試,歡迎參考!
3.54
int decode2(int x,int y,int z)
{
int t=z-y;
int t2=t<<15;
t2=t2>>15;
return (x^t)*t2;
}
3.55
movl 12(%ebp),%esi ;Get x的低位
movl 20(%ebp),%eax ;Get y
movl %eax,%edx
sarl $31,%edx ;取y的符号位
movl %edx,%ecx
imull %esi,%ecx ;%ecx=x的低位*y的符号位(0或者-1)
movl 16(%ebp),%ebx;Get x的高位
imull %eax,%ebx ;%ebx=x的高位*y
addl %ebx,%ecx ;%ecx=x的高位*y+x的低位*y的符号位(0或者-1)
mull %esi ;%edx=(x的低位*y)的高位 %eax=(x的低位*y)的低位
leal (%ecx,%edx),%edx
movl 8(%ebp),%ecx
movl %eax,(%ecx)
movl %edx,4(%ecx)
(x的低位*y)的高位+x的高位*y+x的低位*y的符号位(0或者-1) 存儲在高位
(x的低位*y)的低位 存儲在低位
(xl*y)_h+xh*y+xl*-1
(x1*y)_l
xl=1000
xh=0000
y=1001
x*yi=x*(yu-16)=x*yu-16x
相當于高位=(x*yu)_h-x,低位=(x*yu)_l
因為這裡是mull無符号乘法
3.56
A.
x:%esi,n:%ebx,result:%edi,mask:%edx
B.
result=0x55555555; //0101 0101 0101 0101 0101 0101 0101 0101
mask=0x80000000;
C.
mask!=0
D.
mask每次循環右移n位
E.
result每次循環和x&mask的值進行異或
F.
int loop(int x,int n)
{
int result=0x55555555;
int mask;
for(mask=0x80000000;mask!=0;((unsigned)mask)>>n)//彙編中mask是邏輯右移,而mask是有符号整型應該先轉成無符号整型才能保證C語言的右移操作符編譯成彙編的邏輯右移
{
result^=x&mask;
}
return result;
}
3.57
int cread_alt(int *xp)
{
int t=0;
int *p=xp?xp:&t;
return *p;
}
3.58
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;
case MODE_E:
result=17;
break;
default:
result=-1;
break;
}
return result;
}
3.59
int switch_prob(int x,int n)
{
int result=x;
switch(n)
{
case 40:
case 42:
result<<=3;
break;
case 43:
result>>=3;
break;
case 44:
result<<=3;
result-=x;
case 45:
result*=result;
case 41: //可以不要
default:
result+=11;
break;
}
return result;
}
3.60
A.
A[i][j][k]=A+((2^6-1)*i+9j+k)*4=A+(63i+9j+k)*4
B.
T=9
S*T=63
R*S*T=2772/4=693
R=11 S=7 T=9
3.61
int var_prod_ele(int n, int A[n][n], int B[n][n], int i, int k)
{
int result = 0;
int *a = &A[i][0];
int *b = &B[0][k];
int *e = &A[i][n];
for(;a!=e;)
{
result += *a * *b;
b+=n;
a++;
}
return result;
}
下面是其彙編代碼的循環部分:
edi是4*n,ebx和edx分别是b和a,esi是e,eax是result。
ecx是用于存儲乘法的寄存器。
L4:
movl (%ebx), %ecx
imull (%edx), %ecx
addl %ecx, %eax
addl %edi, %ebx
addl $4, %edx
cmpl %edx, %esi
jne L4
result,Arow,Bcol,4*n這四個值耗費的存儲器必不可少
n的值轉變為e的值耗費一個寄存器
比較n和a的值,省掉了變量j,少用了一個寄存器
3.62
A.
M=76/4=19
B.
i:%edi,j:ecx
C.
void transpose(int A[M][M])
{
for(int i=0;i<M;i++)
{
int *Arr=&A[i][0];
int *Brr=&A[0][i];
for(int j=0;j<i;j++)
{
int t=*Arr;
*Arr=*Brr;
*Brr=t;
Arr+=1;
Brr+=M;
}
}
}
3.63
#define E1(n) 3*n
#define E2(n) 2*n-1
3.64
A.
8(%ebp) &s2
12(%ebp) s1.p
16(%ebp) s1.v
B.
------------%ebp
s2.sum
s2.prod
s1.v
s1.p
&s2
------------%esp
C.将結構的各個成員的值傳遞進方法
D.調用者将傳回值變量的位址傳遞進方法
3.65
A=3 B=7
3.66
A.CNT=196/28=7
B.
typedef struct
{
int idx;
int x[6];
}a_struct;
ap->idx=*(bp+1c*i+4)*4
ap->x[ap->idx]=(bp+4+28*i+4)+*(bp+0x1c*i+4)*4=bp+8+28i+*(bp+28i+4)*4=bp+8+4(7i+*(bp+28i+4))
3.67
A.
e1.p:0
e1.x:4
e2.y:0
e2.next:4
B.8
C.
void proc(union ele *up)
{
up->e2.next->e1.x=*(up->e2.next->e1.p) - up->e2.y;
}
3.68
void good_echo()
{
char c;
int x = 0;
while( x=getchar(), x!='\n' && x!=EOF)
{
putchar(x);
}
}
3.69
A.
long trace(tree_ptr tp)
{
long result=0;
while(tp)
{
result=tp->val;
tp=tp->left;
}
return result;
}
B.輸出二叉樹最左邊節點的值
3.70
A.
long traverse(tree_ptr tp)
{
if(!tp)
return 9223372036854775807;//long.max
long v=tp->val;
long left=traverse(tp->left);
long result=traverse(tp->right);
if(left<result)
result=left;
if(result>v)
result=v;
return result;
}
B.求二叉樹節點中最小的值
原創位址: http://blog.csdn.net/maidou0921/article/details/53907971