逆向-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()

{}

相关推荐
我在人间贩卖青春12 天前
汇编之伪指令
汇编·伪指令
我在人间贩卖青春13 天前
汇编之伪操作
汇编·伪操作
济61713 天前
FreeRTOS基础--堆栈概念与汇编指令实战解析
汇编·嵌入式·freertos
myloveasuka13 天前
汇编TEST指令
汇编
我在人间贩卖青春13 天前
汇编编程驱动LED
汇编·点亮led
我在人间贩卖青春13 天前
汇编和C编程相互调用
汇编·混合编程
myloveasuka14 天前
寻址方式笔记
汇编·笔记·计算机组成原理
请输入蚊子14 天前
《操作系统真象还原》 第六章 完善内核
linux·汇编·操作系统·bochs·操作系统真像还原
myloveasuka14 天前
指令格式举例
汇编·笔记·计算机组成原理
我在人间贩卖青春14 天前
汇编之分支跳转指令
汇编·arm·分支跳转