【发布时间】:2012-11-17 01:13:30
【问题描述】:
我有这个汇编代码:
00000000 <Q2>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 20 sub $0x20,%esp
6: c7 45 fc 1f 00 00 00 movl $0x1f,-0x4(%ebp)
d: c7 45 f8 06 f4 ff ff movl $0xfffff406,-0x8(%ebp)
14: 8b 45 fc mov -0x4(%ebp),%eax
17: 8b 55 08 mov 0x8(%ebp),%edx
1a: 8d 04 02 lea (%edx,%eax,1),%eax
1d: 89 45 f4 mov %eax,-0xc(%ebp)
20: 8b 45 08 mov 0x8(%ebp),%eax
23: 0f af 45 f4 imul -0xc(%ebp),%eax
27: 89 45 f0 mov %eax,-0x10(%ebp)
2a: 8b 45 f8 mov -0x8(%ebp),%eax
2d: 8b 55 f0 mov -0x10(%ebp),%edx
30: 8d 04 02 lea (%edx,%eax,1),%eax
33: 89 45 ec mov %eax,-0x14(%ebp)
36: 83 7d ec 00 cmpl $0x0,-0x14(%ebp)
3a: 74 0a je 46 <Q2+0x46>
3c: b8 00 00 00 00 mov $0x0,%eax
41: 8b 00 mov (%eax),%eax
43: 89 45 f4 mov %eax,-0xc(%ebp)
46: 8b 45 f8 mov -0x8(%ebp),%eax
49: 89 c2 mov %eax,%edx
4b: c1 fa 1f sar $0x1f,%edx
4e: f7 7d 08 idivl 0x8(%ebp)
51: c9 leave
52: c3 ret
我认为分段错误出现在第 4e 行,在它右移十进制 0x1f (31) 后,它会除以 %edx。我认为答案很可能会导致除以0,除非该数字大于或等于2^31。
我被告知是否发生分段错误取决于函数的1个参数的值。在进一步检查汇编代码后,我得出结论,故障与参数无关。我似乎找不到我忽略的东西。有人可以帮忙吗?
【问题讨论】:
-
第 41 行在我看来像是一个段错误。
-
@FrankKotler 如果这是目标文件的
objdump输出,则第 41 行可能有一个不可见的重定位条目。 @John 如果是这样,你可以使用-dr开关吗? -
分段错误不能出现在
4e行,除非您的帧指针 (%ebp) 寄存器损坏。这是因为被零除会导致SIGFPE与siginfo_t具有si_code == FPE_INTDIV。你的函数中没有任何东西可以破坏%ebp,所以如果SIGSEGV出现在那行,你要么有一个非常错误的信号处理程序/自制的上下文切换器(唯一能够改变的用户空间实体%ebp),或内核错误(不太可能)。使用 'gdb' 执行info reg/disas $eip-20 $eip+20。另外 - 您的代码是未优化的编译器输出。来源,请证明“C”标签的合理性;-)
标签: assembly x86 segmentation-fault