我一直在try 嵌入式C编程...非常裸露的金属,唯一的工具链,而不是IDE.为此,我也一直在编写自己的链接器脚本.问题是,当我的C代码中除了main
之外还有任何其他函数时,PC
和SP
(程序计数器和堆栈指针寄存器)就会混乱.
我会提供代码:
左:
ENTRY(start)
MEMORY {
FLASH (rw) : ORIGIN = 0x0000000000000000, LENGTH = 0x000000000000BFFF
RAM (rwx) : ORIGIN = 0x0000000040000000, LENGTH = 0x000000001FFFFFFF
}
_estack = ORIGIN(RAM) + LENGTH(RAM);
SECTIONS {
.text : {
. = ALIGN(4);
*(.text)
} > FLASH
.data : {
. = ALIGN(4);
_sdata = .;
*(.data)
*(.data*)
. = ALIGN(4);
_edata = .;
} > RAM AT> FLASH
.bss : {
_sbss = .;
*(.bss)
*(.bss*)
. = ALIGN(4);
_ebss = .;
} > RAM
}
ASM文件(稍后我将添加更多内容):
.syntax unified
.cpu cortex-a8
.global start
.word _estack
.word _sbss
.word _ebss
.word _sdata
.word _edata
.section .text
start:
ldr sp, =_estack
b main
编译标志还包括:
CFLAGS := -c \
-g
-march=armv7-a \
-nostdlib
QEMU_FLAGS := -m $(MEMORY) \
-S \
-machine cubieboard \
-cpu cortex-a8 \
-gdb tcp::$(PORT)
Problem demonstration:个
C代码:
int main(void) {
volatile int a = 0, b = 1;
for(int i = 2; i < 4; i++) {
int k = a + b;
a = b;
b = k;
}
return 0;
}
Gdb(将架构设置为"arm")输出:
start () at start.s:16
16 ldr sp, =_estack
(gdb) load
Loading section .text, size 0x94 lma 0x0
Start address 0x00000088, load size 148
Transfer rate: 1184 bits in <1 sec, 148 bytes/write.
(gdb) info reg
...
sp 0x0 0x0 <main>
lr 0x0 0
pc 0x88 0x88 <start>
cpsr 0x400001d3 1073742291
fpscr 0x0 0
fpsid 0x410330c0 1090728128
...
Quit
(gdb) step
start () at start.s:18
18 b main
(gdb) step
main () at main.c:1
1 int main(void) {
(gdb) step
3 volatile int a = 0, b = 1;
(gdb) info reg
...
r11 0x5ffffffb 1610612731
r12 0x0 0
sp 0x5fffffe7 0x5fffffe7
lr 0x0 0
pc 0xc 0xc <main+12>
cpsr 0x400001d3 1073742291
fpscr 0x0 0
fpsid 0x410330c0 1090728128
...
也就是说.都很好.
当我有职能时:
C代码:
void my_func(void) {
int volatile c = 1000;
}
int main(void) {
volatile int a = 0, b = 1;
for(int i = 2; i < 4; i++) {
int k = a + b;
a = b;
b = k;
}
my_func();
return 0;
}
Gdb输出:
start () at start.s:16
16 ldr sp, =_estack
(gdb) load
Loading section .text, size 0xbc lma 0x0
Start address 0x000000b0, load size 188
Transfer rate: 1504 bits in <1 sec, 188 bytes/write.
(gdb) step
start () at start.s:18
18 b main
(gdb) step
main () at main.c:5
5 int main(void) {
(gdb) step
my_func () at main.c:3
3 }
(gdb) print a
No symbol "a" in current context.
(gdb) info regs
Undefined info command: "regs". Try "help info".
(gdb) info reg
...
sp 0x0 0x0 <my_func>
lr 0x2c 44
pc 0x14 0x14 <my_func+20>
cpsr 0x400001d7 1073742295
...
(gdb) disas my_func
Dump of assembler code for function my_func:
0x00000000 <+0>: push {r11} @ (str r11, [sp, #-4]!)
0x00000004 <+4>: add r11, sp, #0
0x00000008 <+8>: sub sp, sp, #12
0x0000000c <+12>: mov r3, #1000 @ 0x3e8
0x00000010 <+16>: str r3, [r11, #-8]
=> 0x00000014 <+20>: nop @ (mov r0, r0)
0x00000018 <+24>: add sp, r11, #0
0x0000001c <+28>: pop {r11} @ (ldr r11, [sp], #4)
0x00000020 <+32>: bx lr
End of assembler dump.
(gdb) disas main
Dump of assembler code for function main:
0x00000024 <+0>: push {r11, lr}
0x00000028 <+4>: add r11, sp, #4
0x0000002c <+8>: sub sp, sp, #16
0x00000030 <+12>: mov r3, #0
0x00000034 <+16>: str r3, [r11, #-16]
0x00000038 <+20>: mov r3, #1
0x0000003c <+24>: str r3, [r11, #-20] @ 0xffffffec
0x00000040 <+28>: mov r3, #2
0x00000044 <+32>: str r3, [r11, #-8]
0x00000048 <+36>: b 0x78 <main+84>
0x0000004c <+40>: ldr r2, [r11, #-16]
0x00000050 <+44>: ldr r3, [r11, #-20] @ 0xffffffec
0x00000054 <+48>: add r3, r2, r3
0x00000058 <+52>: str r3, [r11, #-12]
0x0000005c <+56>: ldr r3, [r11, #-20] @ 0xffffffec
0x00000060 <+60>: str r3, [r11, #-16]
0x00000064 <+64>: ldr r3, [r11, #-12]
0x00000068 <+68>: str r3, [r11, #-20] @ 0xffffffec
0x0000006c <+72>: ldr r3, [r11, #-8]
0x00000070 <+76>: add r3, r3, #1
0x00000074 <+80>: str r3, [r11, #-8]
0x00000078 <+84>: ldr r3, [r11, #-8]
0x0000007c <+88>: cmp r3, #3
0x00000080 <+92>: ble 0x4c <main+40>
0x00000084 <+96>: bl 0x0 <my_func>
0x00000088 <+100>: mov r3, #0
0x0000008c <+104>: mov r0, r3
0x00000090 <+108>: sub sp, r11, #4
0x00000094 <+112>: pop {r11, lr}
0x00000098 <+116>: bx lr
(gdb) print &c
$1 = (volatile int *) 0xfffffff8
0xfffffff8扩展到链接器Skript上写入的RAM之外.
有人能解释一下什么是错误的,我如何防止它?