以前的堆栈变量
我有这个问题,我递归调用C中的函数,C是词法范围的,所以我只能访问当前的堆栈帧.我想从前一个函数调用中创建的前一个堆栈帧中提取参数和局部变量,同时我在当前堆栈帧上
我知道前一个递归调用的值仍然在堆栈上,但我无法访问这些值,因为它们被“隐藏”在活动堆栈帧下? 我想从前一个堆栈中提取参数和局部变量,并将它们复制到copy_of_buried_arg和copy_of_buried_loc; 需要使用GAS来提取变量的内联汇编,这是我到目前为止所做的,而且我整天都在尝试,我似乎无法弄明白,我把纸叠在纸上并进行了计算,但没有什么是工作,我也尝试删除对printf的调用,所以堆栈将更清洁,但我不能找出正确的算法.这是到目前为止的代码,我的函数在第二次迭代时停止 #include <stdio.h> char glo = 97; // just for fun 97 is ascii lowercase 'a' int copy_of_buried_arg; char copy_of_buried_loc; void rec(int arg) { char loc; loc = glo + arg * 2; // just for fun,some char arithmetic printf("inside rec() arg=%d loc='%c'n",arg,loc); if (arg != 0) { // after this assembly code runs,the copy_of_buried_arg and // copy_of_buried_loc variables will have arg,loc values from // the frame of the previous call to rec(). __asm__("n movl 28(%esp),%eax #moving stack pointer to old ebp (pointing it to old ebp)n addl $8,%eax #now eax points to the first argument for the old ebp n movl (%eax),%ecx #copy the value inside eax to ecxn movl %ecx,copy_of_buried_arg # copies the old argumentn n "); printf("copy_of_buried_arg=%u copy_of_buried_loc='%c'n",copy_of_buried_arg,copy_of_buried_loc); } else { printf("there is no buried stack framen");// runs if argument = 0 so only the first time } if (arg < 10) { rec(arg + 1); } } int main (int argc,char **argv) { rec(0); return 0; } 解决方法
我可以尝试提供帮助,但在GAS中没有Linux或程序集.但计算应该类似:
这是几次通话后的筹码.典型的堆栈帧设置创建堆栈帧的链接列表,其中EBP是当前堆栈帧并指向其先前堆栈帧的旧值. +-------+ ESP-> |loc='c'| <- ESP currently points here. +-------+ EBP-> |oldEBP |--+ <- rec(0)'s call frame +-------+ | |retaddr| | <- return value of rec(1) +-------+ | |arg=1 | | <- pushed argument of rec(1) +-------+ | |loc='a'| | <- local variable of rec(0) +-------+ | +--|oldEBP |<-+ <- main's call frame | +-------+ | |retaddr| <- return value of rec(0) | +-------+ | |arg=0 | <- pushed argument of rec(0) | +-------+ |/ to main's call frame 这是由以下顺序创建的: >首先推送参数arg. 这对32位堆栈有影响,EBP 8将始终是调用的第一个参数,EBP 12是第二个参数,等等.EBP-n始终是局部变量的偏移量. 然后获取前一个loc和arg的代码(在MASM中): mov ecx,[ebp] // get previous stack frame mov edx,[ecx]+8 // get first argument mov copy_of_buried_arg,edx // save it mov dl,[ecx]-1 // get first char-sized local variable. mov copy_of_buried_loc,dl // save it 或者我对GAS的最好猜测(我不知道但是知道它向MASM倒退): movl (%ebp),ecx movl 8(%ecx),edx movl edx,copy_of_buried_arg movb -1(%ecx),dl movb dl,copy_of_buried_loc 在Windows上使用VS2010使用MASM输出代码: inside rec() arg=0 loc='a' there is no buried stack frame inside rec() arg=1 loc='c' copy_of_buried_arg=0 copy_of_buried_loc='a' inside rec() arg=2 loc='e' copy_of_buried_arg=1 copy_of_buried_loc='c' inside rec() arg=3 loc='g' copy_of_buried_arg=2 copy_of_buried_loc='e' inside rec() arg=4 loc='i' copy_of_buried_arg=3 copy_of_buried_loc='g' inside rec() arg=5 loc='k' copy_of_buried_arg=4 copy_of_buried_loc='i' inside rec() arg=6 loc='m' copy_of_buried_arg=5 copy_of_buried_loc='k' inside rec() arg=7 loc='o' copy_of_buried_arg=6 copy_of_buried_loc='m' inside rec() arg=8 loc='q' copy_of_buried_arg=7 copy_of_buried_loc='o' inside rec() arg=9 loc='s' copy_of_buried_arg=8 copy_of_buried_loc='q' inside rec() arg=10 loc='u' copy_of_buried_arg=9 copy_of_buried_loc='s' (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |