IA32至Y86汇编代码转换

时间:2012-11-30 23:48:35

标签: c assembly instructions y86

我的任务是将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转换的任何提示也将不胜感激。

3 个答案:

答案 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: