- 如图:
long decode2(long x,long y,long z)
{
y -= z;
x *= y;
int tmp = y;
tmp = tmp << 63;
tmp = tmp >> 63;
tmp = x ^ tmp;
return tmp;
}
- 如图:
A:x在%rid中,n在%esi中,result在%eax中,mask在%rdx中
B:result初始值是0,mask初始值是1
C:测试条件是判断mask是否为0
D:mask每次左移n位
E: result |= x & mask
F:代码填写:
long loop(int x,int n)
{
long result = 0;
long mask;
for(mask = 1;mask!=0;mask = mask<<n)
{
result != x & mask;
}
return result;
}
- 如图:
long cread_alt(long *xp)
{
long tmp = 0;
if(!xp)
tmp = *xp;
return tmp;
}
- 如图:
long switch(long *p1,long *p2,mode_t action)
{
long result = 0;
swtich(action)
{
case MODE_A:
result = *p2;
int tmp = *p1;
*p2 = tmp;
break;
case MODE_B:
result = *p1;
result += *p2;
*p1 = result;
break;
case MODE_C:
*p1 = 59;
result = *p2;
break;
case MODE_D: //之后落入E
*p1 = *p2;
case MODE_E:
result = 27;
break;
default:
result = 12;
break;
}
return result;
}
- 如图:
long switch_prob(long x,long n)
{
long result = x;
switch(n)
{
case 0:
case 2:
result = 8x;
break;
case 3:
result = x;
result >> 3;
break;
case 4:
result = x;
result << 4;
x -= x;
case 5:
x = x*x;
case 1:
default:
result = x + 0x4b;
break;
}
return result;
}
-
如图:
A:A[i][j][k] = 首地址+L((ST)i+Sj+k)
B:确定R、S和T的值。
由汇编代码,可以得出RST8 = 3640(条件1)
由汇编代码,A[i][j][k]的位置的公式为A + (65i + 13j + k)8,对照第一问得出的公式,可以得出T =13 ST = 65(条件2)
综合条件1,2,可以计算出R = 7 S = 5 T= 13。 -
如图:
做这个题时应注意 数据对齐
对齐的四个原则规则0:第一个数据成员应该为1,或者是2的倍数 规则1:结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存放在offset为该数据成员大小的整数倍的地方(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。 规则2:如果一个结构体B里嵌套另一个结构体A,则结构体A应从offset为A内部最大成员的整数倍的地方开始存储。(struct B里存有struct A,A里有char,int,double等成员,那A应该从8的整数倍开始存储。),结构体A中的成员的对齐规则仍满足原则1、原则2。 规则3:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。
setVal:
movslq 8(%rsi), %rax # 5 <= B <= 8
addq 32(%rsi), %rax # 9<= A <= 10
movq %rax, 184(%rdi) # 180 <= A * B * 4 <= 184
ret
-
如图:
<test>: mov 0x120(%rsi), %ecx # ecx = *(bp + 288) add (%rsi), %ecx # ecx += *bp # 上两行可推断 288 是 last 与 first 的首地址之差 lea (%rdi, %rdi, 4), %rax # rax = 5i lea (%rsi, %rax, 8), %rax # rax = bp + 40i mov 0x8(%rax), %rdx # rdx = *(bp + 40i + 8) movslq %ecx, %rcx # rcx = ecx(符号扩展) # ecx = n,将其符号扩展,赋值给 x # 由此推断 a_struct 中的 x 是长整型 long 的数组 mov %rcx, 0x10(%rax, %rdx, 8)# 8 * (*(bp + 40i + 8)) + bp + 40i + 16 = rcx retq
比较简单的推断在上图中列出;
难点在mov 0x8(%rax), %rdx # rdx = (bp + 40i + 8)和mov %rcx, 0x10(%rax, %rdx, 8)# 8 * ((bp + 40i + 8)) + bp + 40i + 16 = rcx,bp + 8 + 40i 很容易猜出它是 b_struct 中 a[i] 的首地址,且 b_struct 八字节对齐,结构 a_struct 的字节数为 40;
而 8 * ( *(bp + 40i + 8) ) 可以知道这是索引,进而推断 a_struct 中 idx 排在 x 前面;
那么 bp + 40i + 16 就可以写成 bp + 8 + 40i + 8,前一个 8 是 first 的偏移,后一个 8 是 idx 的偏移;
A.
根据推断,结构 a_struct 的字节数为 40
CNT = (288 - 8)/40 = 7
B.
typedef struct {
long idx;
long x[4];
} a_struct;
-
如图:
A: e1.p 0 e1.y 8 e2.x 0 e2.next 8 B:总共需要16个字节
C:
void proc(union ele *up)
{
up->e2.x = *(up->e2.next->e1.p)-up->e2.next->e1.y;
}
- 如图:
#include<stdio.h>
#define MAX 10
void good_echo() {
char buffer[MAX];
while (fgets(buffer, MAX, stdin) != NULL) {
printf("%s", buffer);
if (ferror(stdin)) {
printf("\nError\n");
return;
}
}
}
- 如图:
A.
通过两个连续的 xmm 寄存器,例如第一个复数参数以 %xmm0 和 %xmm1 传递,第二个以 %xmm2 和 %xmm3 传递,以此类推
B.
%xmm0 作为返回值的实部, %xmm1 作为返回值的虚部