我正在准备计算机科学考试,这个问题在以前的考试中不断出现,我找不到答案。
考虑在只有一种寻址模式(Reg + Offset)的典型 RISC 架构上执行以下两条指令。
804836e: 40 inc %eax
804836f: 89 04 91 mov %eax,(%ecx,%edx,4)
解释 、 证明 的合理性,这两条 IA-32 指令将如何针对此架构编译,使用 IA-32 语法来显示该代码。
评论 在 RISC 架构与 IA-32 上这段代码的大小。
C函数是:
voidpara_par (int a[], int n) {
int i;
for (i=0 ; i<n ; i++) {
if (a[i] & 0x01) {
a[i] += 1;
}
}
}
它接收一个整数数组并增加奇数的值。
以供引用:
%eax -> int i
(%ecx,%edx,4) -> int, part of the array "a" saved to %ecx
我知道这个问题至少可以说含糊不清,但这是我的问题,我真的不知道如何开始从一种架构“转换”到另一种架构。
最佳答案
inc eax
mov [ecx+edx*4],eax
几乎使用了琐碎的指令,那么为什么这也不是类似 RISC 的实际答案?
因为约束是“只有一种寻址模式(Reg + Offset)”。 (而且 RISC 不太可能有
inc
,但这可以通过简单的 add eax,1
来“修复”)。因此,您必须将寻址从
base_reg + index_reg*index_size_imm + ofs
x86 寻址模式转换为 reg + ofs
。如果您暂时考虑一下,没有合理的方法来使用“ofs”部分,除非您创建自修改代码,在执行之前将一些漂亮的代码放入指令操作码中......所以它被缩小到任务“通过(reg + 0)寻址模式来做”。所以你“手动”进行地址计算
add eax,1 ; inc eax
shl edx,2 ; edx = edx*4
add ecx,edx ; ecx = ecx + edx*4
mov [ecx+0],eax
完毕。 (Intel 语法是故意使用的,因为我认为 GAS/AT&T 不应该被人类使用)。
所有关于结果的解释/推理都留给了 OP,因为他应该尝试。 :)(如果您遇到困难,请在评论中告诉我)
顺便说一句,如果你翻译整个 C 部分,它肯定会导致更优化的机器代码,首先没有 *4 乘法,所以 x86 和“RISC”机器代码看起来更相似,除了 x86 可以直接在内存中操作数组元素:
DANG,我设法创建了“增加每个元素”,错过了
if
部分,抱歉......不会修复,因为这以任何方式说明了循环与索引的事情,这是我的初衷要指出,原来mov %eax,(%ecx, %edx, 4)
是相当人为的,在优化的机器代码中几乎找不到。 eax = array + n*4
ecx = -n*4
loop:
inc dword [eax+ecx]
add ecx,4
jnz loop
类似RISC的版本:
ebx = array
ecx = n
loop:
mov eax,[ebx]
add eax,1
mov [ebx],eax
add ebx,4
sub ecx,1
jnz loop
同样不需要索引,这是高级别的东西,通常可以在优化的机器代码中轻松避免,对数据结构有足够的固定约束,就像这里每个元素都是固定的 4 字节大小。
关于assembly - 将 CISC 解释为 RISC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44357342/