我的任务是将IA32代码转换为Y86。原始程序是用C语言编写的,用于获取一个整数数组,其中偶数定位值调用三个函数之一,奇数定位值在该函数内运算。这些功能包括数字的否定,数字的平方以及从1到所提供数字的总和。
大多数指令很容易从IA32转换为Y86,但是有很多指令给我带来了很大的困难。
0000001e <negation>:
1e: 55 push %ebp
1f: 89 e5 mov %esp,%ebp
21: 8b 45 08 mov 0x8(%ebp),%eax
24: f7 d8 neg %eax
26: 5d pop %ebp
27: c3 ret
neg指令不是Y86中的有效指令。这就是我在Y86中所拥有的:
# int Negation(int x)
Negation:
pushl %ebp
pushl %esi
rrmovl %esp,%ebp
mrmovl 0x8(%ebp),%eax
irmovl %esi,$0
subl %eax, %esi
rrmovl %esi, %eax
popl %esi
popl %ebp
ret
这是解决此问题的正确方法吗?
另一条指令是我的square函数中的imul指令:
00000028 <square>:
28: 55 push %ebp
29: 89 e5 mov %esp,%ebp
2b: 8b 45 08 mov 0x8(%ebp),%eax
2e: 0f af c0 imul %eax,%eax
31: 5d pop %ebp
32: c3 ret
有谁知道在这种情况下如何转换“imul”指令?
感谢您的帮助!关于IA32 / Y86转换的任何提示也将不胜感激。
答案 0 :(得分:1)
为了实现imul
,您可能希望使用shift和add例程来实现mul
例程:
然后对于imul
,只需使用以下步骤:
mul
例行程序
答案 1 :(得分:0)
1)是mrmovl 0x4(%esp),允许%eax?
ixorl %eax, 0xffffffff
iaddl %eax, 1
应该稍微更有效率(ebp也可以用作GPR - 无需推送esi)
2)对于乘法,确实存在shift和add-options,
但也是一种基于LUT的方法,利用了4*a*b = (a+b)^2 - (a-b)^2
的事实。
对于每个8x8位或NxN位乘法。
对于a=h<<8+l, B=H<<8|L, aB = Ll + (hL+Hl)<<8 + hH<<16;
可以使用3个不同的表来处理:
s1[n] = n^2 >>2; s2[n]=n^2 << 6; s3[n]=n^2 << 14;
答案 2 :(得分:0)
对于否定,你反转了irmovl指令的操作数。
以下代码有效:
#
# Negate a number in %ebx by subtracting it from 0
#
Start:
irmovl $999, %eax // Some random value to prove non-destructiveness
irmovl Stack, %esp // Set the stack
pushl %eax // Preserve
Go:
irmovl $300, %ebx
xorl %eax, %eax
subl %ebx,%eax
rrmovl %eax, %ebx
Finish:
popl %eax // Restore
halt
.pos 0x0100
Stack: