Intel Pentium Assembler x86汇编程序代码生成

时间:2014-04-29 08:47:58

标签: assembly compiler-construction x86

提前感谢您的时间!我目前正在制作迷你pascal编译器。扫描,解析和语义分析正在运行,我处于代码生成阶段。我遇到了一些我生成的代码,我不完全理解为什么它不起作用。它可以编译,但输出完全关闭。我将首先链接示例程序,然后链接生成的汇编代码。

type recordType = record of {
                x: int,
                y: int
              };

func a(x : int, y : int) : recordType
  var p2 : recordType;
  allocate p2;
  p2.x = x;
  p2.y = y;
  return p2;
end a

var p1 : recordType;
p1 = a(10,2);

write p1.x / p1.y;

由于汇编程序代码非常大(由于尚未进行优化),我将链接函数a的代码,因为我认为问题就在那里。如果你想要完整的例子,我很乐意发布它,但除非被要求,否则我不会垃圾论坛。

函数a的汇编代码如下所示:

a:
    pushl %ebp
    movl %esp, %ebp
    lea -8(%ebp), %eax
    pushl %eax
    popl %eax
    imul $8, %eax
    pushl %eax
    call malloc
    addl $4, %esp
    movl %eax, -8(%ebp)
    lea -8(%ebp), %eax
    pushl %eax
    popl %eax
    addl $4, %eax
    pushl %eax
    movl 12(%ebp), %eax
    pushl %eax
    popl %eax
    popl %ebx
    movl %eax, (%ebx)
    lea -8(%ebp), %eax
    pushl %eax
    popl %eax
    addl $0, %eax
    pushl %eax
    movl 8(%ebp), %eax
    pushl %eax
    popl %eax
    popl %ebx
    movl %eax, (%ebx)
    movl -8(%ebp), %eax
    pushl %eax
    popl %eax
    jmp aend
aend:
   movl %ebp, %esp
   popl %ebp
   ret

现在在你说什么之前。我知道有很多冗余代码,这是因为我还没有优化代码。话虽如此,我想谈谈所使用的惯例。根据它们的大小(int,bool和array是4个字节,其中记录的总大小等于其成员大小的总和)和参数x和y保存+偏离basepointer(%ebp)+根据basepointer使用-offset保存局部变量(params从+8开始,locals从-4开始)。请记住,AT& T样式的汇编程序使用常规movl src,dst,它与普通汇编程序不同。

我认为问题可能在于根据basepointer在lea指令和movl或我的索引之间的混合。无论如何它可以编译并给我一个3的一致结果,当它应该是5.我已经测试了我的分区,它似乎与"正常"整数。

非常感谢任何帮助。提前谢谢!

此致 马格努斯

1 个答案:

答案 0 :(得分:0)

由于lea -8(%ebp),%eax计算地址,指令imul $8,%eax将地址乘以8 ...为什么?

代码movl %eax,-8(%ebp)将%eax存储在stackpointer下方。所以这个价值将无法存活很长时间!

代码movl %eax,(%ebx)也存储在stackpointer下面,因为%ebx现在包含有效地址-4(%ebp)。当%ebx包含有效地址-8(%ebp)时,会发生第10次这种情况。

也许您需要做的是用subl $8,%espmovl %esp,%eax替换第三条指令。这确实会为您的局部变量建立一个区域。