使用不超过 $3$ 条 $x86$ 指令实现如下函数: 其中 $x, y, z, w$ 分别存储于 %rdi, %rsi, %rdx, %rcx. 返回值存储于 %rax.
long add(long x, long y, long z, long w) { return 32 * x + 8 * y + 4 * z + w; }
add: leaq (%rsi,%rdi,4), %rsi leaq (%rcx,%rsi,8), %rcx leaq (%rcx,%rdx,4), %rcx ret
$X86-64$ 体系结构中的条件跳转指令 $jg$ 是用于带符号数比较还是无符号数比较的? 其产生跳转的成立条件是 ~(SF^OF) & ~ZF 为真, 请解释为何是这一条件.
答:
条件跳转指令 $jg$ 是用于带符号数比较的.
考虑被比较的两个数 $a, b$, 当 $\text{~(SF^OF)&~ZF}$ 为真时:
有 $\text{~(SF^OF)}$ 为真, 则 $\text{SF^OF}$为假, 从而 $\text{SF = OF = 1}$ 或 $\text{SF = OF = 0}$,
即此时 $a\le b$.
同时有 $\text{~ZF}$ 为真, 则 $\text{ZF}$为假, 从而 $\text{ZF = 0}$,
即此时 $a\ne b$.
故 $a < b$ 成立.
有如下对应的 $C$ 代码与汇编代码 $(x86-64)$, 请对照着填上代码中缺失的部分(数字请用十进制表示).
call_swap: subq $24, %rsp movl __①__, 12(%rsp) movl $91125, 8(%rsp) leaq 8(%rsp), %rsi leaq 12(%rsp), __④__ movl $0, %eax call swap
void swap(int *a, int *b); void call_swap() { int zip1 = 15213; int zip2 = __②__; __③__; }
① : $15213
② : 91125
③ : swap(&zip1, &zip2)
④ : %rdi
一个 $C$ 语言的 $for$ 循环代码 (部分) 及其 $64$ 位 $Linux$ 汇编如下所示, 请对照汇编填充 $C$ 语言里的缺失部分.
int looper(int n, int *a) { int i; int x = 0; for (i = 0; i < n; i++) { if (x < a[i] - 1) x = 2 * a[i]; else x += 1; } return x; }
looper: movl $0, %eax movl $0, %edx jmp .L2 .L4: movslq %edx, %rcx movl (%rsi,%rcx,4), %ecx addl $1, %eax cmpl %eax, %ecx jle .L3 leal (%rcx,%rcx), %eax .L3: addl $1, %edx .L2: cmpl %edi, %edx jl .L4 ret
对于如下代码
long v2permute(long *array, long x, long y, long z) { long t1 = 8253 * x; long t2 = array[t1 + 2 * y]; long t3 = array[t2 * 16 + z]; long t4 = t1 + t2 + t3; long t5 = array[0] * t1; long ret = t3 & t5; return ret; }
对应如下汇编指令, 请写出每条指令之后目标寄存器存储的变量/临时变量值.
v2permute: movq %rdx, %r8 movq %rcx, %rdx imulq $8253, %rsi, %rax leaq (%rax,%r8,2), %rcx movq (%rdi,%rcx,8), %rcx salq $4, %rcx addq %rdx, %rcx imulq (%rdi), %rax andq (%rdi,%rcx,8), %rax
① : y
② : z
③ : 8253 * x
④ : 8253 x + 2 y
⑤ : array[8253 x + 2 y]
⑥ : 16 array[8253 x + 2 * y]
⑦ : 16 array[8253 x + 2 * y] + z
⑧ : array[0] 8253 x
⑨ : array[16 array[8253 x + 2 y] + z] & (array[0] 8253 * x)
请对照下面的 $C$ 语言代码与相应汇编 $(Linux X86-64)$, 给出 $M$、$N$ 的值.
copy_element: movslq %edi, %rdi movslq %esi, %rsi leaq (%rsi,%rsi,2), %rax leaq (%rsi,%rax,4), %rax addq %rdi, %rax movl mat2(,%rax,4), %edx leaq 0(,%rdi,8), %rax subq %rdi, %rax addq %rax, %rsi movl %edx, mat1(,%rsi,4) ret
#define M 13 #define N 7 int mat1[M][N]; int mat2[N][M]; int copy_element(int i, int j) { mat1[i][j] = mat2[j][i]; }
上一篇
俄罗斯概况
俄罗斯文化常识
2022-10-09
下一篇
计算机系统概论 作业1
整数、浮点数作业
2022-10-03