stack 에서 esp 를 감소시킬때..

arimae의 이미지

함수를 호출할때 내부적으로 선언한 데이터의 크기만큼 esp 를 조정을 하게 되는데, gcc -S 를 이용해서 어셈 코드를 생성한 것을 보고 궁금한 점이 있어 글을 올립니다.

#include <stdio.h>

int main(int argc, char *argv[])
{
    int a;
    int b;
    int c;
    int d;

    return 0;
}

위의 경우에는 정상적으로 int 형의 크기 * 4 = 16 byte 만큼 esp에서 감소를 시킵니다. 단순히 int 형으로 하나씩 선언할 경우에는 선언이 하나 증가할때 마다 esp 에서 4씨 더 빼주게 됩니다.

        .file   "test3.c"
        .version        "01.01"
gcc2_compiled.:
.text
        .align 4
.globl main
        .type    main,@function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $16, %esp
        movl    $0, %eax
        leave
        ret
.Lfe1:
        .size    main,.Lfe1-main
        .ident  "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.1)"

다른 방법으로 이제 배열로 테스트 해봤더니 배열은 다른 결과가 나오더군요.
처음 int a[1], int a[2] 까지는 4, 8 byte 씨 esp 에서 빼다가 int a[3] 의 경우 12가 아닌 갑자기 24 byte를 빼더군요. 그리고 int a[4] 의 경우 역시 24byte 를 빼다가 int a[5] 에서는 40 byte를 빼게 됩니다. 즉 일정 간격마다 16 byte 씩 증가하게 됩니다.

#include <stdio.h>

int main(int argc, char *argv[])
{
    int a[5];

    return 0;
}

        .file   "test3.c"
        .version        "01.01"
gcc2_compiled.:
.text
        .align 4
.globl main
        .type    main,@function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $40, %esp
        movl    $0, %eax
        leave
        ret
.Lfe1:
        .size    main,.Lfe1-main
        .ident  "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.1)"

gcc 3.3.3 에서도 비슷하게 감소 되더군요.
main 함수 뿐만 아니라 일반 함수에서도 이런 현상이 발생하는데, 왜 이렇게 구현했는지 궁금합니다. 아마 일부러 gcc 에서 이렇게 만드는것 같은데, 보안 문제 때문이 아닐까 추측을 해보았지만, 정확한 답은 모르겠더군요.

어셈쪽에 지식이 얕아 이렇게 글을 올립니다. 잘 아시는 분의 명쾌한 답변 기다리겠습니다.

bugiii의 이미지

스택에 놓은 지역변수들의 접근성을 좋게 하기위해서 일부러 16바이트 정렬을 하는 것 같습니다.

함수 본체도 그런식으로 정렬하는 경우가 있죠. (대부분 그렇게 할겁니다.)

캐쉬가 그렇게 되어야 히트수가 높아지니까 성능상 이득이 많다고 알고 있습니다.

jyj9782의 이미지

넹 2.96 이전버전은 4바이트 정렬..
이후는 16바이트 정렬 .. 이라고 알고 있어요.
저런 성능상의 이유였군요.
고맙습니다

힘내세요.

arimae의 이미지

성능 상의 이유였군요.. 답변 주셔서 감사합니다.

Dream, Passion and Challenge..

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.