逆向-beginners之栈

#if 0

栈是最基础的数据结构之一。

从技术上说,栈就是CPU寄存器里的某个指针所指向的一片内存区域。这里所说的"某个指针"通常位于x86/x64平台的ESP/RSP,ARM的SP。

操作栈的最常见的指令是push/pop。

push 会对ESP/RSP/SP的值进行减法运算,使之减去 4(32 bit)或 8(64 bit),然后将操作数写到上述寄存器里的指针所指向的内存中。

pop 先从栈指针(stack pointer)指向的内存中读取数据,用以备用(通常是写到其他寄存器里),然后再将栈指针的数值加上 4 或 8 。

在分配栈的空间之后,栈指针,即stack pointer所指向的地址是栈的底部。push 将减少栈指针的数值,而 pop 会增加它的数值。

栈的"底"实际上使用的是整个栈的最低地址,即是整个栈的启动内存地址。

/*

* 栈的用途

*/

1.保存函数结束时的返回地址

/* x86 */

当程序使用call调用其他函数时,call指令结束后的返回地址将被保存在栈里;

在call所调用的函数结束之后,程序将执行无条件跳转指令,跳转到这个返回地址。

call 等价于 "PUSH 返回地址" 和 "JMP 函数地址" 的指令对。

被调用函数里的RET指令,会从栈中读取返回地址,然后跳转到这个地址,就相当于"POP 返回地址" + "JMP 返回地址"指令。

栈是有限的,溢出它很容易。直接使用无限递归,本就会满。

/* arm */

ARM程序也使用栈保存返回地址,只是略有不同。程序的返回地址保存在LR里。但是,如果程序还会继续调用其他函数,就需要在调用函数

之前保存LR的值。通常,函数会在启动过程中(序言处)保存LR的值。通常在函数序言处看到"push R4-R7,LR", 并在尾声处看到

"pop R4-R7, PC"。这些指令会对函数自身将要用到的寄存器进行保护,把它们的值放在栈中---也包括LR。

如果一个函数不调用其他函数,它就像对上的枝杈末端的叶子那样。这种函数就叫作"叶函数(leaf function)"。叶函数的特点是,它不必

保存LR的值。如果叶函数的代码短到用不到几个寄存器,那么它可能根本不会使用数据栈。所以,调用叶函数的时候确实可能不会涉及栈

操作。这种情况下,因为这种代码不在外部内存RAM进行与栈有关的操作,所以它的运行速度有可能超过X86系统。在没有分配栈或者不可能用栈的时候,这类函数就会显现出优势。

2.参数传递

esp + 4 : 返回地址

esp + 8 : 参数一

ese + c : 参数二

ese + 10 : 参数三

3.存储局部变量

4.alloca

alloca函数直接使用栈来分配内存,除此之外,它与malloc没有显著区别。用完退出,自动释放。

/*

* 栈的噪音

*/

原有栈空间里的局部变量不会被自动清除,就成为了噪音或脏数据了。

#endif

void main()

{}

相关推荐
老鱼说AI2 小时前
深入理解计算机系统1.5:抽象的重要性:操作系统与虚拟机
c语言·开发语言·汇编
猫猫的小茶馆1 天前
【Linux 驱动开发】一. 搭建开发环境
linux·汇编·arm开发·驱动开发·stm32·嵌入式硬件·mcu
猫猫的小茶馆1 天前
【Linux 驱动开发】二. linux内核模块
linux·汇编·arm开发·驱动开发·stm32·嵌入式硬件·架构
切糕师学AI2 天前
ARM 中的 SVC 监管调用(Supervisor Call)
linux·c语言·汇编·arm开发
ベadvance courageouslyミ2 天前
硬件基础中断
汇编·硬件·中断
你爱写程序吗(新H)2 天前
基于单片机的洗衣机控制系统设计 单片机洗衣机控制(设计+文档)
c语言·汇编·单片机·嵌入式硬件·matlab
VekiSon3 天前
ARM架构——用汇编语言点亮 LED
汇编·arm开发·嵌入式硬件
JJCar4 天前
汇编文字池(literal pool)
汇编·文字池·literal pool
乾复道4 天前
巧用终端,每天节省2小时
汇编·经验分享·vim
2501_927773075 天前
嵌入式——汇编语言1
汇编