首页 文章

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

提问于
浏览
1

在此先感谢您的时间!我目前正在制作迷你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

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

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

任何帮助深表感谢 . 提前致谢!

关心马格努斯

1 回答

  • 0

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

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

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

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

相关问题