以下函数,
#include <string.h>
void func1(char *s)
{
char buffer[4];
strcpy(buffer, s);
}
已编译,
$ arm-linux-gnueabi-gcc -g -fno-stack-protector func1.c -c -o func1.o
$ arm-linux-gnueabi-gcc --version
arm-linux-gnueabi-gcc (Ubuntu 13.2.0-4ubuntu3) 13.2.0
并拆卸:
$ arm-linux-gnueabi-objdump --disassemble=func1 -S func1.o
void func1(char *s)
{
0: e92d4800 push {fp, lr}
4: e28db004 add fp, sp, #4
8: e24dd010 sub sp, sp, #16
c: e50b0010 str r0, [fp, #-16]
char buffer[4];
strcpy(buffer, s);
10: e24b3008 sub r3, fp, #8
14: e51b1010 ldr r1, [fp, #-16]
18: e1a00003 mov r0, r3
1c: ebfffffe bl 0 <strcpy>
}
20: e1a00000 nop @ (mov r0, r0)
24: e24bd004 sub sp, fp, #4
28: e8bd8800 pop {fp, pc}
我的分析strcpy()
:调用(指令)之后0x20
堆栈有以下内容:
|---+---+---+---|
fp - 20 | ????????? | <- current $sp
|---+---+---+---|
fp - 16 | char * s | <- $r1
|---+---+---+---|
fp - 12 | ????????? |
|---+---+---+---|
fp - 8 | char buffer[] | <- $r0, $r3
|---+---+---+---|
fp - 4 | prev $fp | <- $sp after push
|---+---+---+---|
| $lr | <- $fp
|---+---+---+---|
| | | | | <- $sp that had the calling function
|---+---+---+---|
.
.
.
^
| descending addresses
问题:
$sp
指向的内容是什么?由于 ARM 使用完整的降序堆栈,因此该元素被标记为已占用,并且被调用的函数不会使用该空间。- 为什么这两个局部变量之间有未使用的空间?