免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 8080 | 回复: 12
打印 上一主题 下一主题

C语言中是什么控制着函数嵌套调用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-09-03 15:41 |只看该作者 |倒序浏览
5可用积分
最近遇到个问题,大致是这样的:
函数A()中调用函数B(),函数B()调用函数C()程序就跑飞了;
而将C()的所有实现在函数B()中实现,功能都正常!
我想,代码肯定是没有问题的,编译ok。
我想知道是什么控制着函数嵌套的次数?

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2011-09-03 16:23 |只看该作者
回复 1# jyhhappyjyh


    在 C 中,只要你的棧夠大,函數可以一直嵌套下去。你的問題,恐怕還是在你覺得肯定沒問題的地方,也即你的代碼寫的有問題,例如在 C() 中把棧破壞了。

论坛徽章:
0
3 [报告]
发表于 2011-09-03 18:01 |只看该作者
回复 2# MMMIX


    应该不是代码的问题!因为我在进函数的一开始就加入了调试,结果没有执行!
在进入C代码之前我给SP分配了8K的空间,应该是能满足我这点代码的要求了!
我唯一怀疑的是不是链接脚本中有哪里可以修改的?

  1. OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips",
  2.               "elf32-littlemips")

  3. OUTPUT_ARCH(mips:isa32)
  4. SEARCH_DIR(/opt/test)
  5. ENTRY(_start)

  6. MEMORY
  7. {
  8.         ram        : ORIGIN = 0x80060000 , LENGTH = 0x7ff00000
  9. }

  10. SECTIONS
  11. {
  12.         . = 0x80060000;
  13.     .interp ALIGN (0x4) : { *(.interp) } > ram
  14.         .hash : AT ((LOADADDR (.interp) + SIZEOF (.interp) + 0x40 - 1) & ~ (0x40 - 1)) { *(.hash) } > ram
  15.         .dynsym : AT ((LOADADDR (.hash) + SIZEOF (.hash) + 0x40 - 1) & ~ (0x40 - 1)) { *(.dynsym) } > ram
  16.         .dynstr : AT ((LOADADDR (.dynsym) + SIZEOF (.dynsym) + 0x40 - 1) & ~ (0x40 - 1)) { *(.dynstr) } > ram
  17.         .gnu.version : AT ((LOADADDR (.dynstr) + SIZEOF (.dynstr) + 0x40 - 1) & ~ (0x40 - 1)) { *(.gnu.version) } > ram
  18.         .gnu.version_d : AT ((LOADADDR (.gnu.version) + SIZEOF (.gnu.version) + 0x40 - 1) & ~ (0x40 - 1)) { *(.gnu.version_d) } > ram
  19.         .gnu.version_r : AT ((LOADADDR (.gnu.version_d) + SIZEOF (.gnu.version_d) + 0x40 - 1) & ~ (0x40 - 1)) { *(.gnu.version_r) } > ram
  20.         .plt : AT ((LOADADDR (.gnu.version_r) + SIZEOF (.gnu.version_r) + 0x40 - 1) & ~ (0x40 - 1)) { *(.plt) } > ram
  21.     .rel.text : { *(.rel.text) *(.rel.text.*) *(.rel.gnu.linkonce.t*) } > ram
  22.     .rela.text : { *(.rela.text) *(.rela.text.*) *(.rela.gnu.linkonce.t*) } > ram
  23.     .rel.data : { *(.rel.data) *(.rel.data.*) *(.rel.gnu.linkonce.d*) } > ram
  24.     .rela.data : { *(.rela.data) *(.rela.data.*) *(.rela.gnu.linkonce.d*) } > ram
  25.     .rel.rodata : { *(.rel.rodata) *(.rel.rodata.*) *(.rel.gnu.linkonce.r*) } > ram
  26.     .rela.rodata : { *(.rela.rodata) *(.rela.rodata.*) *(.rela.gnu.linkonce.r*) } > ram
  27.     .rel.got : { *(.rel.got) } > ram .rela.got : { *(.rela.got) } > ram
  28.     .rel.ctors : { *(.rel.ctors) } > ram .rela.ctors : { *(.rela.ctors) } > ram
  29.     .rel.dtors : { *(.rel.dtors) } > ram .rela.dtors : { *(.rela.dtors) } > ram
  30.     .rel.init : { *(.rel.init) } > ram .rela.init : { *(.rela.init) } > ram
  31.     .rel.fini : { *(.rel.fini) } > ram .rela.fini : { *(.rela.fini) } > ram
  32.     .rel.bss : { *(.rel.bss) } > ram .rela.bss : { *(.rela.bss) } > ram
  33.     .rel.plt : { *(.rel.plt) } > ram .rela.plt : { *(.rela.plt) } > ram
  34.     .rel.dyn : { *(.rel.dyn) } > ram
  35.     .jcr ALIGN (0x4) : { . = .; *(.jcr) } > ram
  36.     .init ALIGN (0x4) : { . = .; KEEP (*(.init)) } > ram =0
  37.     .text ALIGN (0x4) : { _stext = .; _ftext = . ; *(.text) *(.text.*)  *(.stub) *(.gnu.warning) *(.gnu.linkonce.t*) *(.mips16.fn.*) *(.mips16.call.*) } > ram =0 _etext = .; PROVIDE (etext = .);
  38.     .fini ALIGN (0x4) : { . = .; KEEP (*(.fini)) } > ram =0
  39.     .rodata ALIGN (0x8) : { . = .; *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) } > ram
  40.     .rodata1 ALIGN (0x8) : { . = .; *(.rodata1) *(.rodata1.*) } > ram
  41.     .data ALIGN (0x8) : { __ram_data_start = ABSOLUTE (.); _fdata = . ; *(.data) *(.data.*) *(.gnu.linkonce.d*) *( .2ram.*) . = ALIGN (8); SORT(CONSTRUCTORS) } > ram __rom_data_start = LOADADDR(.data);
  42.     .data1 ALIGN (0x8) : { . = .; *(.data1) *(.data1.*) } > ram
  43.     .eh_frame ALIGN (0x4) : { . = .; *(.eh_frame) } > ram
  44.     .gcc_except_table ALIGN (0x4) : { . = .; *(.gcc_except_table) } > ram
  45.     .ctors ALIGN (0x4) : { . = .; KEEP (*crtbegin.o(.ctors)) __CTOR_LIST__ = .; PROVIDE (__CTOR_LIST__ = .); KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) __CTOR_END__ = .; PROVIDE (__CTOR_END__ = .); } > ram
  46.     .dtors ALIGN (0x4) : { . = .; KEEP (*crtbegin.o(.dtors)) __DTOR_LIST__ = .; PROVIDE (__DTOR_LIST__ = .); KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) __DTOR_END__ = .; PROVIDE (__DTOR_END__ = .); } > ram
  47.     .devtab ALIGN (0x4) : { . = .; KEEP(*( SORT (.ecos.table.*))) ; } > ram
  48.     _gp = ALIGN(16) + 0x7ff0; .got ALIGN (0x4) : { . = .; *(.got.plt) *(.got) } > ram
  49.     .dynamic ALIGN (0x4) : { . = .; *(.dynamic) } > ram
  50.     .sdata ALIGN (0x4) : { . = .; *(.sdata) *(.sdata.*) *(.gnu.linkonce.s*) } > ram
  51.     .lit8 ALIGN (0x8) : { . = .; *(.lit8) } > ram
  52.     .lit4 : AT ((LOADADDR (.lit8) + SIZEOF (.lit8) + 0x40 - 1) & ~ (0x40 - 1)) { . = .; *(.lit4) } > ram __ram_data_end = .; _edata = . ; PROVIDE (edata = .);
  53.     _fbss = .; .sbss ALIGN (0x8) : { . = .; *(.dynsbss) *(.sbss) *(.sbss.*) *(.scommon) } > ram
  54.     .bss ALIGN (0x8) : {__bss_start = .; *(.dynbss) *(.bss) *(.bss.*) *(COMMON) } > ram __bss_end = .;
  55.     __heap1 = ALIGN (0x8);
  56.     . = ALIGN(4);
  57.         _end = .;
  58.         PROVIDE (end = .);
  59.         .stab 0 : { *(.stab) }
  60.         .stabstr 0 : { *(.stabstr) }
  61.         .stab.excl 0 : { *(.stab.excl) }
  62.         .stab.exclstr 0 : { *(.stab.exclstr) }
  63.         .stab.index 0 : { *(.stab.index) }
  64.         .stab.indexstr 0 : { *(.stab.indexstr) }
  65.         .comment 0 : { *(.comment) }
  66.         .debug 0 : { *(.debug) }
  67.         .line 0 : { *(.line) }
  68.         .debug_srcinfo 0 : { *(.debug_srcinfo) }
  69.         .debug_sfnames 0 : { *(.debug_sfnames) }
  70.         .debug_aranges 0 : { *(.debug_aranges) }
  71.         .debug_pubnames 0 : { *(.debug_pubnames) }
  72.         .debug_info 0 : { *(.debug_info) }
  73.         .debug_abbrev 0 : { *(.debug_abbrev) }
  74.         .debug_line 0 : { *(.debug_line) }
  75.         .debug_frame 0 : { *(.debug_frame) }
  76.         .debug_str 0 : { *(.debug_str) }
  77.         .debug_loc 0 : { *(.debug_loc) }
  78.         .debug_macinfo 0 : { *(.debug_macinfo) }
  79.         .debug_weaknames 0 : { *(.debug_weaknames) }
  80.         .debug_funcnames 0 : { *(.debug_funcnames) }
  81.         .debug_typenames 0 : { *(.debug_typenames) }
  82.         .debug_varnames 0 : { *(.debug_varnames) }
  83.         .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
  84.         .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
  85.         /DISCARD/ 0 : { *(.mdebug) }
  86. }
复制代码

论坛徽章:
1
天蝎座
日期:2013-12-06 18:23:58
4 [报告]
发表于 2011-09-03 18:35 |只看该作者
回复 3# jyhhappyjyh


    你这么发,错误不好找吧,一楼说的很有道理,C返回的时候把栈破坏了。你可以把ABC 贴出来看看~~

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
5 [报告]
发表于 2011-09-03 18:39 |只看该作者
回复  MMMIX


    应该不是代码的问题!因为我在进函数的一开始就加入了调试,结果没有执行!
在进入 ...
jyhhappyjyh 发表于 2011-09-03 18:01



    在找到確實的問題之前,不要輕易的下結論,這樣往往是堵塞了自己的思路,平白的浪費許多時間。那種「我肯定自己的代碼沒問題,結果查下來恰恰是自己代碼有問題」的情況我已經碰到過很多次了。

论坛徽章:
0
6 [报告]
发表于 2011-09-04 12:36 |只看该作者
有个方法验证下就知道问题在不在自己了,把代码实现全注释掉


  1. void fa()
  2. {
  3.    /**/
  4. }

  5. void fb()
  6. {
  7.    fa()  
  8. /**/
  9. }
  10. void fc()
  11. {
  12.   fb()
  13. /**/
  14. }
复制代码

论坛徽章:
0
7 [报告]
发表于 2011-09-05 10:54 |只看该作者
回复 5# MMMIX


    谢谢MMMIX兄的建议!

论坛徽章:
0
8 [报告]
发表于 2011-09-06 11:06 |只看该作者
回复 6# duanjigang


    我把我的代码全部去掉,只留下调试的一部分。
我把代码全部贴出来,大家看看!
首先,在进入C代码之前初始化gp和sp:
boot.S
  1. #include "mipsdef.h"

  2. #define CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE 8092
  3. ##-----------------------------------------------------------------------------
  4. ## Startup code
  5.         .text
  6.        
  7. FUNC_START(_start)
  8.         # Load Global Pointer register.
  9.         la        gp,_gp

  10.         # load initial stack pointer
  11.         la        a0,__interrupt_stack
  12.         move        sp,a0

  13.         #clear bss
  14.        


  15.         # Call c_main       

  16.         .extern        c_main
  17.         j         c_main
  18.     lui     ra,0
  19.        
  20. FUNC_END(_start)

  21.         .bss       
  22.         .balign 16
  23.         .rept CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE
  24.         .byte 0
  25.         .endr
  26. __interrupt_stack:

  27.         .long        0,0,0,0,0,0,0,0
复制代码
接下来进入C函数main.c:
  1. /**************************************************
  2. *
  3. *  Main C entry point
  4. *
  5. **************************************************/
  6. #include "ag7100.h"

  7. extern void fa(void);
  8. extern void fb(void);
  9. extern void fc(void);
  10. extern void fd(void);
  11.        
  12. void c_main(void)
  13. {
  14.         ar7100_reg_wr(AR7100_GPIO_OE, ar7100_reg_rd(AR7100_GPIO_OE)|(1<<1)|(1<<0) );
  15.         fa();
  16. }
复制代码
fa()、fb()、fc()和fd()在下一级目录test中的test.c中:
  1. void fd(void)
  2. {
  3.         ;
  4. }

  5. void fc(void)
  6. {
  7.         fd();
  8. }

  9. void fb(void)
  10. {
  11.         fc();
  12. }

  13. void fa(void)
  14. {
  15.         ar7100_reg_wr(AR7100_GPIO_OUT, ar7100_reg_rd(AR7100_GPIO_OUT)^(1<<1));
  16.         fb();
  17. }
复制代码
这里的ag7100_reg_wr()是一个宏,用于写GPIO寄存器,点亮一个led
主Makefile如下:
  1. #####################################################
  2. #
  3. #
  4. # JYH added to compile main.c
  5. #
  6. #
  7. #####################################################

  8. INSTALL_DIR        = /home/extend/export/atheros/build/mipsisa32-elf
  9. COMMAND_PREFIX     = mipsisa32-elf-
  10. HEADER_DIR                   = $(shell pwd)/include


  11. XCC           = $(INSTALL_DIR)/bin/$(COMMAND_PREFIX)gcc
  12. XLD           = $(INSTALL_DIR)/bin/$(COMMAND_PREFIX)ld

  13. CFLAGS        = -I$(INSTALL_DIR)/include -I$(INSTALL_DIR)/3.2.1/include -I$(HEADER_DIR)
  14. LDFLAGS       = -L$(INSTALL_DIR)/lib -static
  15. OBJECTS       = boot.o main.o test.o

  16. export XCC
  17. export XLD
  18. export CFLAGS
  19. export LDFLAGS

  20. LDFLAGS       += -T $(shell pwd)/target.ld
  21. # RULES

  22. .PHONY: all clean

  23. all:MTest

  24. MTest:$(OBJECTS)
  25.         $(XLD) -o $@ $^ $(LDFLAGS)

  26. boot.o: boot.S
  27.         $(XCC) $(CFLAGS) -o $@ -c $^ $(LDFLAGS)

  28. main.o:main.c
  29.         $(XCC) $(CFLAGS) -o $@ -c $^ $(LDFLAGS)

  30. test.o:
  31.         $(MAKE) -C test

  32. clean:
  33.         -rm -f MTest *.o
复制代码
进入test目录之后的Makefile为:
  1. #####################################################
  2. #
  3. #
  4. # JYH added to compile test.c
  5. #
  6. #
  7. #####################################################

  8. LDFLAGS       += -G0

  9. .PHONY: test.o

  10. test.o:test.c
  11.         $(XCC) $(CFLAGS) -o test.o $< $(LDFLAGS)
  12.         mv test.o ../
复制代码
现在的现象是:
1. 如果将点亮led放在fa()中,小灯可以被成功的点亮,如果将点灯放入fb()中,fb()由fa()调用,小灯不能被点亮!
2. 如果将fa()、fb()、fc()和fd()都放在main.c中,则小灯均会被点亮,函数调用正常!

我开始怀疑是我的Makefile最后的链接写得有问题,请高手指导一下!
(我编译的时候提示 warning: cannot find entry symbol _start; defaulting to 0000000080060028
)

论坛徽章:
0
9 [报告]
发表于 2011-09-06 11:07 |只看该作者
回复 4# crazyhadoop


    请 crazyhadoop 兄也帮忙再看看!代码和最新的现象我贴在上面了!

论坛徽章:
0
10 [报告]
发表于 2011-09-06 11:08 |只看该作者
回复 5# MMMIX


    请MMMIX 再帮忙看看!谢谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP