gcc가 이상합니다. 함수호출시 이상한짓(?)을 하네요.

lifego의 이미지

간단한 코드를 어셈블해봤습니다.
그랬드니 gcc가 조금 이상한짓(?)을 하는것같아서 질문드립니다.

pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16 , %esp <--이건 왜이렇게 하는것일까요.. :roll:
movl $0 , %eax <--이거하고 밑의줄은 전혀 의미없는 동작 아닐까요? :cry:
subl %eax,%esp
....

lifego의 이미지

검색해보니 나오네요..ㅜㅜ
16바이트 얼라인문제는 알것같은데요...
($0부분은 잘 몰겠네요...ㅠㅠ)

http://www.ale.org/archive/ale/ale-2002-08/msg00147.html

What you have seen is that gcc is maintaining the stack alignment
at a 16-byte boundary. This is to prevent potential problems when
using the Streaming SIMD (single instruction multiple data)
Extensions (SSE) first introduced on Pentium III CPUs. These
extensions added some new instructions and a set of 8 128-bit
registers (XMM0 to XMM7) to the CPU. Some of the new instructions
will cause a general protection fault when moving 128-bit data to or
from memory which is not on a 16-byte boundary. While there are
alternative instructions which can access 128-bit data on arbitrary
boundaries, they are less efficient.

In the example you gave, the stack had the following items on it:

4 bytes: return address
4 bytes: old frame pointer
12 bytes: x[10]
8 bytes: y[5]

That's a total of 28 bytes, requiring an additional 4 bytes of
padding for alignment to the nearest 16-byte boundary. Therefore, to
make room for x[10], y[5], plus padding, the stack pointer must be
decremented by 12 + 8 + 4 = 24 bytes.

In your example however, the stack pointer is decremented by 40
rather than 24. The result is still properly aligned, but an
additional 16 bytes of space is wasted. This is just a peculiarity
of the compiler version you are using. I think you will find this
waste is eliminated in the latest versions of gcc.

Incidentally, you can also observe stack alignment being performed
when setting up function calls. Some example code:

extern int foo (char bar);

int foobar (void)
{
return foo (0);
}

In the resulting assembly code, you see %esp reduced by 8 which
maintains stack alignment on function entry. Then you see %esp
reduced an additional 12 before pushing 4 more bytes on the stack and
calling foo(), again maintaining alignment. On return from the
function call, 16 bytes are removed from the stack:

foobar:
pushl %ebp
movl %esp,%ebp
subl $8,%esp
addl $-12,%esp
pushl $0
call foo
addl $16,%esp
movl %eax,%edx
movl %edx,%eax
jmp .L2
.p2align 4,,7
.L2:
leave
ret

All of this alignment behavior is controlled by the
"-mpreferred-stack-boundary=" compiler option. The default is for
16-byte alignment, but the default can be overridden.

--Joe

-----Original Message-----
From: Benjamin Dixon [SMTP:beatle@arches.uga.edu]
Sent: Monday, July 29, 2002 3:26 PM
To: ale@ale.org
Subject: [ale] linux byte alignment

Hi all,

I'm trying to pry into linux byte alignment issues and assembly and I ran
across something I haven't figured out. My understanding is that alignment
is at one word (4 bytes) so I have the following function:

int main()
{
char x[10];
char y[5];
}

By my calculation, if the memory has to be alignment, x[10] will take up
12 bytes (ceiling of 2.5 words = 3, 3x4-bytes = 12). And likewise, the
y[5] will take up 8 bytes. So there's 20 bytes of excess memory laying
around? But when I run the program through gcc with the -S option, I get
the following:

..
main:
pushl %ebp
movl %esp,%ebp
subl $40,%esp
.L2:
movl %ebp,%esp
popl %ebp
ret
.Lfe1:
..

The question is, what's that 40? If I use different numbers for the array
sizes, I get a different number there, always divisible by 4 but always
greater than the number I expect. Anyone know why?

Ben

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.