汇编 - 如何修改堆栈大小?

Ahm*_*oum 5 windows x86 assembly

我是汇编编程的新手,我正在使用使用内存堆栈的推送和弹出指令。那么,堆栈默认大小是多少,如何修改它以及它的大小限制是多少?

Rai*_*ers 5

堆栈大小取决于很多因素。这取决于堆栈的启动位置、有多少内存、使用的 CPU 等等。您使用的 CPU 不称为“Windows CPU”。如果您指定正在使用的 CPU,则需要详细指定该 CPU 的名称,以及非常重要的 CPU 架构。在这种情况下,您可能使用 x86 架构。

这是 x86 架构的内存映射:


All addresses Before 0X100000 - Free
0x100000 - 0xc0000 - BIOS
0xc0000 - 0xa0000 - Video Memory
0xa0000 - 0x9fc00 - Extended BIOS data area
0x9fC00 - 0x7e00 - Free
0x7e00 - 0x7c00 - Boot loader
0x7c00 - 0x500 - Free
0x500 - 0x400 - BIOS data area
0x400 - 0x00 - Interupt vector table
Run Code Online (Sandbox Code Playgroud)

在 x86 中,堆栈信息由两个寄存器保存:


    Base pointer (bp): Holds starting address of the stack
    Stack pointer (sp): Holds the address in which next value will be stored
Run Code Online (Sandbox Code Playgroud)

这些寄存器在不同模式下有不同的名称:


                            `Base pointer           Stack pointer`
    16 bit real mode:       bp                     sp
    32 bit protected mode:  ebp                    esp
    64 bit mode:            rbp                    rsp
Run Code Online (Sandbox Code Playgroud)

当您设置堆栈时,堆栈指针和基指针获得相同的地址。

堆栈设置在基址指针寄存器指定的地址中。
您可以在内存中任何空闲的地方设置堆栈,并且堆栈向下增长。

每次将某些内容“推入”堆栈时,该值都会存储在堆栈指针(与开头的基指针相同)指定的地址中,并且堆栈指针寄存器会递减。

每次从堆栈中“弹出”某些内容时,存储在堆栈指针寄存器指定的地址中的值将存储在程序员指定的寄存器中,并且堆栈指针寄存器会递增。

在 16 位实模式中,您可以“推入”和“弹出”16 位。因此,每次“压入”或“弹出”时,堆栈指针寄存器都会递减或递增 0x02,因为每个地址保存 8 位。

在 32 位保护模式下,“压入”和“弹出”32 位。因此,每次“压入”或“弹出”时,堆栈指针寄存器都会递减或递增 0x04,因为每个地址保存 8 位。

您必须将堆栈设置在正确的位置,具体取决于您要“推送”的值的数量。

如果你继续“推动”你的堆栈不断向下增长,在某个时间点你的堆栈可能会覆盖某些东西。因此,明智的做法是将堆栈设置在内存中的某个地址中,该地址有足够的空间供堆栈向下增长。

例如:
如果您将堆栈设置在引导加载程序下方的 0x7c00 处,并且您“推送”了太多值,则您的堆栈可能会在某个时间点覆盖 BIOS 数据区域,从而导致大量错误。

现在您应该对堆栈及其大小有基本的了解。