C 如何确定堆栈是向上增加还是向下增加?
如何确定堆栈是向上增加还是向下增加?一种可能的方法是C 如何确定堆栈是向上增加还是向下增加?,c,C,如何确定堆栈是向上增加还是向下增加?一种可能的方法是 #include <stdio.h> void call(int *a) { int b; if (&b > a) printf("Stack grows up.\n"); else printf("Stack grows down.\n"); } int main () { int a; call(&a); ret
#include <stdio.h>
void call(int *a)
{
int b;
if (&b > a)
printf("Stack grows up.\n");
else
printf("Stack grows down.\n");
}
int main ()
{
int a;
call(&a);
return 0;
}
#包括
无效调用(int*a)
{
int b;
如果(&b>a)
printf(“堆栈长大。\n”);
其他的
printf(“堆栈向下生长。\n”);
}
int main()
{
INTA;
呼叫(&a);
返回0;
}
一种可能的方法是
#include <stdio.h>
void call(int *a)
{
int b;
if (&b > a)
printf("Stack grows up.\n");
else
printf("Stack grows down.\n");
}
int main ()
{
int a;
call(&a);
return 0;
}
#包括
无效调用(int*a)
{
int b;
如果(&b>a)
printf(“堆栈长大。\n”);
其他的
printf(“堆栈向下生长。\n”);
}
int main()
{
INTA;
呼叫(&a);
返回0;
}
暴力方法是用已知值(比如0xFF)填充内存。将一些项目推到堆栈上。进行内存转储。在堆栈上再推一些项目。执行另一个内存转储。暴力方法是用已知值(例如0xFF)填充内存。将一些项目推到堆栈上。进行内存转储。在堆栈上再推一些项目。执行另一个内存转储。这非常依赖于平台,甚至依赖于应用程序
Vino发布的代码只在参数在堆栈上传递,局部变量按该顺序从堆栈中分配的目标中起作用。许多编译器将为参数分配固定内存地址,或在寄存器中传递参数。在堆栈上传递参数虽然很常见,但却是将数据输入和输出函数的最低效方法之一
查看已编译应用程序的反汇编,并查看编译器生成的代码。如果您的目标具有编译器正在使用的本机堆栈操作命令(如PUSH和POP),那么CPU数据表/参考手册将告诉您堆栈的增长方向。但是,编译器可能会选择实现自己的堆栈,在这种情况下,您必须进行一些挖掘
或者,读取堆栈指针,按下堆栈上的某个内容,然后再次读取堆栈指针。比较第一次和第二次读取的结果,以确定指针移动的方向
供将来参考:如果您包括一些关于您的目标体系结构(嵌入式?PC?Linux、Windows?GCC?VC?Watcom?等等)的详细信息,您将得到更有意义的答案。这非常依赖于平台,甚至依赖于应用程序
Vino发布的代码只在参数在堆栈上传递,局部变量按该顺序从堆栈中分配的目标中起作用。许多编译器将为参数分配固定内存地址,或在寄存器中传递参数。在堆栈上传递参数虽然很常见,但却是将数据输入和输出函数的最低效方法之一
查看已编译应用程序的反汇编,并查看编译器生成的代码。如果您的目标具有编译器正在使用的本机堆栈操作命令(如PUSH和POP),那么CPU数据表/参考手册将告诉您堆栈的增长方向。但是,编译器可能会选择实现自己的堆栈,在这种情况下,您必须进行一些挖掘
或者,读取堆栈指针,按下堆栈上的某个内容,然后再次读取堆栈指针。比较第一次和第二次读取的结果,以确定指针移动的方向
供将来参考:如果您包括一些关于您的目标体系结构(嵌入式?PC?Linux、Windows?GCC?VC?Watcom?等等)的详细信息,您将得到更有意义的答案。使用许多局部变量创建函数。
关闭优化。
要么打印汇编语言。。
或者在调试时,显示为混合源代码和汇编语言。
在执行函数之前,请注意堆栈指针(或寄存器)。
单步执行函数并观察堆栈指针
一般来说,编译器是否使用递增或递减堆栈指针是一个非常小的问题,只要该问题是一致且有效的。这是一个很少占据我头脑的问题。我倾向于关注更重要的话题,比如质量、正确性和健壮性
我相信编译器能够正确处理堆栈操作。我不信任递归函数,尤其是在嵌入式或受限平台上。使用许多局部变量创建函数。
关闭优化。
要么打印汇编语言。。
或者在调试时,显示为混合源代码和汇编语言。
在执行函数之前,请注意堆栈指针(或寄存器)。
单步执行函数并观察堆栈指针
一般来说,编译器是否使用递增或递减堆栈指针是一个非常小的问题,只要该问题是一致且有效的。这是一个很少占据我头脑的问题。我倾向于关注更重要的话题,比如质量、正确性和健壮性
我相信编译器能够正确处理堆栈操作。我不信任递归函数,尤其是在嵌入式或受限平台上。这假设所讨论的编译器在堆栈上传递参数,并且局部变量也从堆栈中分配。这是不能保证的,实际上效率很低。这在很大程度上取决于编译器如何实现函数调用和局部变量。我会在字符串末尾添加\n
。+1。虽然这是一种依赖于实现的黑客行为,但堆栈本身可以被视为一种依赖于实现的黑客行为。OP本质上是在问一个依赖于平台的问题,他应该对依赖于平台的答案感到满意。@David Lively——我在发表评论时实际上考虑了8051,这就是我使用“标准C实现”的原因。我为8051使用的C不是ANSI C,因为它有3种不同类型的指针,因为有3种不同的地址空间(堆栈、数据和代码),并且它有可交换的寄存器组IIRC。AVR和MSP430在RAM空间中也有寄存器,但是如果您传递addr