Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何确定堆栈是向上增加还是向下增加?_C - Fatal编程技术网

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