【发布时间】:2014-04-29 08:47:57
【问题描述】:
提前感谢您的宝贵时间!我目前正在制作一个迷你帕斯卡编译器。扫描、解析和语义分析正在工作,我正处于代码生成阶段。我遇到了一些我生成的代码,我不完全理解它为什么不起作用。它可以编译,但输出完全关闭。我会先链接示例程序,再链接生成的汇编代码。
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 个字节,其中记录的总大小等于其成员大小的总和)与基指针 (%ebp) 保存 + 偏移量,并且局部变量根据基指针以 -offset 保存(参数从 +8 开始,局部变量从 -4 开始)。请记住,AT&T 风格的汇编器使用约定 movl src, dst,这与普通汇编器不同。
我认为问题可能在于 lea 指令和 movl 之间的混合,或者我根据基指针的索引。无论如何,它可以编译并给我一个一致的结果 3,而它应该是 5。我已经测试了我的除法,它似乎适用于“正常”整数。
非常感谢任何帮助。提前致谢!
问候 马格纳斯
【问题讨论】:
标签: assembly compiler-construction x86