我有这个家庭作业,我应该写一个c程序,显示传递给调用堆栈中的前一个函数的参数到控制台。我有这段代码:
struct stack_frame
{
struct stack_frame* next;
};
typedef struct stack_frame stack_frame;
void recover()
{
register stack_frame* sfptr __asm__("ebp");
stack_frame * frame = sfptr;
traverse_stack(frame, show_bytes);
}
对函数foo(int,short,char)的几次递归调用在调用recover()之前发生,它启动堆栈的遍历,导致所有先前调用foo的参数输出。
当我使用gcc 4.8.2编译它而没有优化时,它运行得很好。使用-O1会因帧被分配一个无法访问的地址而中断。 0xffffffd9。我相信这是因为asm正在逐步优化。
我已经尝试了很多其他方法来获取ebp寄存器的值,包括
stack_frame frame;
asm volatile("movl %%ebp, %0\n" : "=r"(frame->next));
和其他许多人。我试过添加clobbers。我也尝试将帧指定为volatile。我已经审阅过很多关于这个主题的SO帖子,包括[问题]:gcc removes inline assembler code和其他人。无论我尝试过什么,我都是SegFault City的国王。
此处发生了段错误:
void traverse_stack(stack_frame* frame, byte_processor show_bytes)
{
if (frame->next != NULL) // segfault here!!!!!!!
traverse_stack(frame, show_bytes);
show_args(frame, show_bytes);
}
show_bytes只是一个指向两个函数之一的函数指针,它将以十六进制显示大端或小端系统的字节。
无论如何,我必须使用-m32进行编译。我没有提供任何额外参数的选择。
非常感谢任何帮助。此外,我有点新手,所以如果可能的话,请温柔地回答你的问题。提前谢谢。