|
刚才在另一个帖子里才发现我们一直使用WINAVR编译LGT的代码的Stack初始化错了
初始化Stack的汇编代码如下:
652: cf ef ldi r28, 0xFF ; 255
654: d2 e0 ldi r29, 0x04 ; 2
656: de bf out 0x3e, r29 ; 62
658: cd bf out 0x3d, r28 ; 61
可以看到stack被初始化成0x4ff,LGT的stack最大值只有0x2ff,因此这样子初始化后LGT对应的stack是0xff, 已经落在SRAM之外了。
这样子程序应该很不正常才是。结果看起来运行的挺好。(不知为什么,难道SPH写 0x4 执行不成功?)
为解决这个问题我们需要手动修改winavr的相关文件。
我们用WINAVR编译LGT的时候是用mega164p (以WinAVR-20090313为例)
WinAVR-20090313\avr\include\avr\iom164.h里有个RAMEND的宏,但是修改这个宏的值到0x2ff 重新编译还是一样。
WinAVR-20090313\avr\lib\avr5\crtm164p.o 这个是初始化的一段代码
先用objdump打印出汇编代码:
其中有个.init2的段
Disassembly of section .init2:
00000000 <.init2>:
0: 11 24 eor r1, r1
2: 1f be out 0x3f, r1 ; 63
4: c0 e0 ldi r28, 0x00 ; 0
6: d0 e0 ldi r29, 0x00 ; 0
8: de bf out 0x3e, r29 ; 62
a: cd bf out 0x3d, r28 ; 61
用 readelf看这个段有一个relocation
Relocation section '.rela.init2' at offset 0x990 contains 2 entries:
Offset Info Type Sym.Value Sym. Name + Addend
00000004 00002a06 R_AVR_LO8_LDI 000004ff __stack + 0
00000006 00002a07 R_AVR_HI8_LDI 000004ff __stack + 0
就是把.init2里面偏移4和6的地方换成0x4ff
这个就是stack的大小了。
用utraedit打开.o文件,找到“FF 04” 这个值,把它改成“FF 02” 就可以了 (注意要备份原文件)。
重新编译再看汇编就会改过来了:
652: cf ef ldi r28, 0xFF ; 255
654: d2 e0 ldi r29, 0x02 ; 2
656: de bf out 0x3e, r29 ; 62
658: cd bf out 0x3d, r28 ; 61
|
|