对齐堆栈是什么意思? [英] What does it mean to align the stack?

查看:26
本文介绍了对齐堆栈是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直是一名高级程序员,架构对我来说还很陌生,所以我决定在这里阅读有关汇编的教程:

I have been a high-level coder, and architectures are pretty new to me, so I decided to read the tutorial on Assembly here:

http://en.wikibooks.org/wiki/X86_Assembly/Print_Version

在教程的后面,说明如何转换 Hello World!程序

Far down the tutorial, instructions on how to convert the Hello World! program

#include <stdio.h>

int main(void) {
    printf("Hello, world!
");
    return 0;
}

给出等效的汇编代码并生成以下内容:

into equivalent assembly code was given and the following was generated:

        .text
LC0:
        .ascii "Hello, world!12"
.globl _main
_main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        movl    $0, %eax
        movl    %eax, -4(%ebp)
        movl    -4(%ebp), %eax
        call    __alloca
        call    ___main
        movl    $LC0, (%esp)
        call    _printf
        movl    $0, %eax
        leave
        ret

对于其中一行,

andl    $-16, %esp

解释是:

此代码和"ESP 与 0xFFFFFFF0,将堆栈与下一个对齐最低 16 字节边界.一个Mingw 源代码的检查表明这可能适用于 SIMD出现在_main"中的说明例程,仅对对齐的地址.因为我们的日常没有包含 SIMD 指令,这一行没有必要.

This code "and"s ESP with 0xFFFFFFF0, aligning the stack with the next lowest 16-byte boundary. An examination of Mingw's source code reveals that this may be for SIMD instructions appearing in the "_main" routine, which operate only on aligned addresses. Since our routine doesn't contain SIMD instructions, this line is unnecessary.

我不明白这一点.有人能给我解释一下将堆栈与下一个 16 字节边界对齐意味着什么以及为什么需要它吗?andl 是如何实现这一点的?

I do not understand this point. Can someone give me an explanation of what it means to align the stack with the next 16-byte boundary and why it is required? And how is the andl achieving this?

推荐答案

假设在 _main 入口处的栈是这样的(栈指针的地址只是一个例子):

Assume the stack looks like this on entry to _main (the address of the stack pointer is just an example):

|    existing     |
|  stack content  |
+-----------------+  <--- 0xbfff1230

按下%ebp%esp减8,为局部变量留出一些空间:

Push %ebp, and subtract 8 from %esp to reserve some space for local variables:

|    existing     |
|  stack content  |
+-----------------+  <--- 0xbfff1230
|      %ebp       |
+-----------------+  <--- 0xbfff122c
:    reserved     :
:     space       :
+-----------------+  <--- 0xbfff1224

现在,andl 指令将 %esp 的低 4 位清零,这可以减少它;在此特定示例中,它具有保留额外 4 个字节的效果:

Now, the andl instruction zeroes the low 4 bits of %esp, which may decrease it; in this particular example, it has the effect of reserving an additional 4 bytes:

|    existing     |
|  stack content  |
+-----------------+  <--- 0xbfff1230
|      %ebp       |
+-----------------+  <--- 0xbfff122c
:    reserved     :
:     space       :
+ - - - - - - - - +  <--- 0xbfff1224
:   extra space   :
+-----------------+  <--- 0xbfff1220

重点是有一些SIMD"(单指令,多数据)指令(在 x86 领域也称为SSE",表示Streaming SIMD Extensions")可以对多个字执行并行操作内存,但要求这些多个字是从 16 字节倍数的地址开始的块.

The point of this is that there are some "SIMD" (Single Instruction, Multiple Data) instructions (also known in x86-land as "SSE" for "Streaming SIMD Extensions") which can perform parallel operations on multiple words in memory, but require those multiple words to be a block starting at an address which is a multiple of 16 bytes.

通常,编译器不能假设 %esp 的特定偏移量会产生合适的地址(因为 %esp 在函数入口处的状态取决于调用代码).但是,通过以这种方式故意对齐堆栈指针,编译器知道将 16 字节的任意倍数添加到堆栈指针将导致 16 字节对齐的地址,这对于这些 SIMD 指令是安全的.

In general, the compiler can't assume that particular offsets from %esp will result in a suitable address (because the state of %esp on entry to the function depends on the calling code). But, by deliberately aligning the stack pointer in this way, the compiler knows that adding any multiple of 16 bytes to the stack pointer will result in a 16-byte aligned address, which is safe for use with these SIMD instructions.

这篇关于对齐堆栈是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆