我正准备进行计算机科学测试,而且这个问题在以前的测试中不断出现,我找不到答案。
考虑在典型的RISC架构上执行以下两条指令,只有一种寻址模式(Reg + Offset)。
804836e: 40 inc %eax
804836f: 89 04 91 mov %eax,(%ecx,%edx,4)
解释,证明,如何使用IA-32 sintaxe为此体系结构编译这两条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;
}
}
}
它接收一个int数组并递增奇数值。
供参考:
%eax -> int i
(%ecx,%edx,4) -> int, part of the array "a" saved to %ecx
我知道这个问题至少可以说是模糊的,但那是我的问题,我真的不知道如何从一个架构开始“翻译”到另一个架构。
答案 0 :(得分:1)
inc eax
mov [ecx+edx*4],eax
几乎是使用琐碎的指令,为什么这对RISC来说也不是真正的答案?
因为约束是&#34;只有一种寻址模式(Reg + Offset)。&#34; (并且RISC也不太可能inc
,但这可以通过简单的add eax,1
修复&#34;
因此,您必须将寻址从base_reg + index_reg*index_size_imm + ofs
x86寻址模式转换为reg + ofs
。如果你会在短时间内考虑它,那么就没有合理的方法来使用&#34; ofs&#34;部分,除非你创建自修改代码,在执行它之前将一些漂亮的东西放入指令操作码中......所以它缩小到任务&#34;通过(reg + 0)寻址模式&#34;
所以你做地址数学&#34;手动&#34;
add eax,1 ; inc eax
shl edx,2 ; edx = edx*4
add ecx,edx ; ecx = ecx + edx*4
mov [ecx+0],eax
完成。 (故意使用英特尔语法,因为我不认为GAS / AT&amp; T应该被人类使用)。
关于结果留给OP的所有解释/推理,因为他应该尝试。 :)(如果你遇到困难,请在评论中告诉我) 顺便说一句,如果你要翻译整个C部分,它肯定会导致更优化的机器代码,而不是首先乘以* 4,所以x86和&#34; RISC&#34;机器代码看起来会更相似,除了x86可以直接在内存中操作数组元素: DANG,我设法创建&#34;增加每个元素&#34;,错过了if
部分,抱歉....不会修复,因为这说明了循环vs索引的事情,这是我最初指出的原因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字节大小。