3.62
type def enum {MODE_A, MODE_B, MODE_C, MODE_D, MODE_E} mode_t;
long switch3(long *p1, long *p2, mode_t action)
{
long result = 0;
switch(action) {
case MODE_A:
result = *p2;
*p2 = *p1;
break;
case MODE_B:
result = *p1 + *p2;
*p1 = result;
break;
case MODE_C:
*p1 = 59;
result = *p2;
break;
case MODE_D:
*p1 = *p2;
result = 27;
break;
case E:
result = 27;
break;
default:
result = 12;
}
3.63
long switch_prob(long x, long n) {
long result = x;
switch(n) {
case 60:
case 62:
result = 8 * x;
break;
case 63:
result = x >> 3;
break;
case 64:
x = x << 4 - x; // x *= 15;
case 65:
x *= x;
default:
result = x + 75;
}
return result;
}
3.64
A.
B. 翻译代码得到坐标计算公式为:
确定
返回值为3640,所以
确定
3.65
A. %rdx ; B. %rax ; C.
3.66
#define NR(n) (3 * (n))
#define NC(n) (4 * (n) + 1)
3.67
A. 以eval的原始栈顶为基准
相对地址 | 值 |
---|---|
0 | 原始栈顶 |
... | 未定义 |
-80 | z |
-88 | &z |
-96 | y |
-104 | x |
B. 传递了整个结构体 strA,包括 x y &z
C. 利用%rsp+偏移量进行访问
D. 利用%rdi+偏移量进行访问
E. 同样利用%rsp+偏移量进行访问
相对地址 | 值 |
---|---|
0 | 原始栈顶 |
... | 未定义 |
-24 | z |
-32 | x |
-40 | y |
... | 未定义 |
-80 | z |
-88 | &z |
-96 | y |
-104 | x |
3.68 对齐原则:
setVal:
movslq 8(%rsi), %rax # int4字节对齐,所以4 < B <= 8
addq 32(%rax), %rax # long8字节对齐,所以24 < 12+2*A <= 32 --> 6 < A <= 10
movq %rax, 184(%rdi) # long8字节对齐,所以176 < 4*A*B <= 184 --> 44 < A*B <= 46
ret # 综上,A=5, B=9是唯一解
3.69
mov 0x120(%rsi), %ecx # ecx = *(bp+288)
add (%rsi), %ecx # ecx += *(bp) 推断:last和first地址差为288
lea (%rdi,%rdi,4),%rax
lea (%rsi,%rax,8),%rax # rax = 40i + bp
mov 0x8(%rax),%rdx # rdx = *(40i+8+bp) 推断:a_struct的字节数为40
movslq %ecx,%rcx
mov %rcx,0x10(%rax,%rdx,8) # *(10+rax+8rdx) = (long)n 推断a_struct中的x是long类型的数组
retq
A. CNT = (288-8)/40 = 7
B.
typedef struct {
long idx;
long x[4];
} a_struct;
3.70
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);
}
3.72
A. 分配的栈空间大小为(8n+30)&0xFFFFFFF0,所以
B.
利用偏置,向上舍入到距离s2最近的16的倍数;
C. 已知,
由A和B可知
于是
得出结论,s1 = 16k+1,且n为偶数时,e1取最小值1。s1 = 16k时,且x为奇数时,s1取最大值24。其中k为任意正整数。
D. s2为8*n的数组分配空间足够的空间偏移量为
3.73 测试代码使用原文代码:
#include<stdio.h>
range_t find_range(float x);
typedef enum {NEG, ZERO, POS, OTHER} range_t;
range_t find_range_ans(float x)
{
int result;
if (x < 0)
result = NEG;
else if (x == 0)
result = ZERO;
else if (x > 0)
result = POS;
else
result = OTHER;
return result;
}
range_t find_range(float x)
{
asm(
"vxorps %xmm1, %xmm1, %xmm1;"
"movl $0, %eax;"
"vucomiss %xmm1, %xmm0;"
"jp .L0;"
"jb .DONE;"
"je .L2;"
"ja .L1;"
".L0: addl $1, %eax;"
".L1: addl $1, %eax;"
".L2: addl $1, %eax;"
".DONE: nop;"
);
}
3.74
range_t find_range(float x)
{
asm(
"vxorps %xmm1, %xmm1, %xmm1;"
"movl $0, %eax;"
"movl $1, %r8d;"
"movl $2, %r9d;"
"movl $3, %r10d;"
"vucomiss %xmm1, %xmm0;"
"cmova %r9d, %eax;"
"cmove %r8d, %eax;"
"cmovp %r10d, %eax;"
);
}
3.75
A. 通过两个连续的XMM寄存器传递
B. XMM0返回复数的实部,XMM1返回虚部