繁体   English   中英

ARM处理器:堆栈内容

[英]ARM Processor : Content of stack

我正在尝试分析ARM Binary的objdump。

我发现在我的情况下,局部变量的数量为2个整数,每个整数的大小为4个字节。 该函数没有参数。 我希望函数将堆栈指针减8,但是堆栈指针减16。

这发生在我测试集中的所有功能中。

有人可以帮我了解发生了什么吗? 或将我指向一些我可以阅读以理解的文档。

编辑:如果有帮助,它是32位ARM 11处理器。

此外,功能参数正在寄存器中发送。

从我的小型测试集中,我看到SP的值比局部变量的大小增加了8。

编辑2:

这是一些代码。

Objdump

    0000036c <adpcm_coder>:
 36c:   e92d0ff0    push    {r4, r5, r6, r7, r8, r9, sl, fp}
 370:   e24dd010    sub sp, sp, #16   ; <-- Decrement of SP
 374:   e58d0004    str r0, [sp, #4]
 378:   e58d300c    str r3, [sp, #12]
 37c:   e1d330f0    ldrsh   r3, [r3]
 380:   e59d000c    ldr r0, [sp, #12]
 384:   e5d0c002    ldrb    ip, [r0, #2]
 388:   e59f0118    ldr r0, [pc, #280]  ; 4a8 <adpcm_coder+0x13c>
 38c:   e790010c    ldr r0, [r0, ip, lsl #2]
 390:   e3520000    cmp r2, #0
 394:   da00003d    ble 490 <adpcm_coder+0x124>
 398:   e58d1000    str r1, [sp]

GDB的一些输出可能会有所帮助。

$ arm-none-eabi-gdb my_ctop_IR.elf

(gdb) target sim
Connected to the simulator.

(gdb) load
Loading section .text, size 0x898 vma 0x0
Loading section .rodata, size 0x200 vma 0x898
Loading section .data, size 0x14e768 vma 0xa98
Start address 0x40
Transfer rate: 10981376 bits in <1 sec.

(gdb) b adpcm_coder
Breakpoint 1 at 0x37c: file adpcm_IR.c, line 106.

(gdb) run
Starting program: /home/gaurav/eclipse-workspace/hostCompiledSimulation/instrument/examples/adpcm/my_ctop_IR.elf 

Breakpoint 1, adpcm_coder (indata=0x14f208, outdata=0x154208 "", len=10240, state=0x14f204) at adpcm_IR.c:106
106   valpred = state->valprev;

(gdb) info scope adpcm_coder
Scope for adpcm_coder:
Symbol indata is a variable with multiple locations, length 4.
Symbol outdata is a variable with multiple locations, length 4.
Symbol len is a variable with multiple locations, length 4.
Symbol state is a variable with multiple locations, length 4.
Symbol valpred_41 is optimized out.
Symbol index_40 is a variable with multiple locations, length 4.
Symbol index_38 is optimized out.
Symbol delta_37 is a variable with multiple locations, length 4.
Symbol step_36 is a variable with multiple locations, length 4.
Symbol step_35 is a variable with multiple locations, length 4.
Symbol valpred_34 is a variable with multiple locations, length 4.
Symbol ivtmp_28 is a variable in register r8, length 4.
Symbol bufferstep is a variable in register r6, length 4.
Symbol outputbuffer is a variable with complex or multiple locations (DWARF2), length 4.
Symbol index is a variable with multiple locations, length 4.
Symbol vpdiff is a variable with multiple locations, length 4.
Symbol valpred is a variable with multiple locations, length 4.
Symbol step is a variable with multiple locations, length 4.
Symbol diff is a variable with multiple locations, length 4.
Symbol delta is a variable with multiple locations, length 4.
Symbol sign is a variable in register r7, length 4.
Symbol outp is a variable with complex or multiple locations (DWARF2), length 4.

我还必须指出,该函数的源代码实际上具有更多的局部变量,但是这些似乎已由编译器进行了优化。 当我尝试打印gdb命令信息范围输出中列出的变量的地址时,我只看到2个变量的地址在堆栈中。 这就是我得出的结论,即该函数只有2个局部变量。

问候,高拉夫

除了您的两个变量外,这些函数(如果它们不是叶子函数)也将需要将返回地址保存在某个地方,以便它们可以返回。 另外,普通的ARM ABI要求堆栈始终保持8字节对齐。 因此,总共有12个字节需要存储在堆栈中,将其舍入为8的倍数以进行对齐。

叶子函数不需要任何堆栈空间,因为它们不需要保存返回地址,并且可以将本地变量保留在暂存寄存器中(如果有4个或更少的本地变量)。

实际上,您的2个整数可能不属于堆栈中使用的16个字节的一部分。 ARM是RISC处理器,一种加载/存储架构。 这意味着它永远不会直接在内存中工作。 取而代之的是,它使用内部寄存器,从内存中加载值,计算这些值,然后将其存储在内存中。

如果您的两个整数仅存在于函数中,则将其放入内存中将毫无用处。 寄存器将完成工作,并且您避免了加载/存储操作。

那么,您的堆栈中有什么? 唯一知道的方法是看一下装配。 幸运的是,ARM汇编非常易于阅读。 但让我们猜测一下:如果您的函数调用了另一个函数,则必须保留返回地址(最初在lr寄存器中),您将必须加载函数地址(通常无法通过直接寻址来调用),并且您将必须保存寄存器,您调用的功能可能会修改。

很难做出准确的猜测,这实际上取决于您的功能。 向我们提供您的功能的反汇编,我们将能够准确告诉您发生了什么。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM