[완료] 함수 호출시 esp 관련 질문

hongwoo의 이미지

swap.c 가 아래와 같이 되어있고.,

void swap(int *a, int *b) {
    int t = *a;
    *a = *b;
    *b = t;
}

gcc -S swap.c

해서.. swap.s를 보면 esp를 16만큼 줄이는데요..,

        .file   "swap.c"
        .text
.globl swap
        .type   swap, @function
swap:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $16, %esp
        movl    8(%ebp), %eax
        movl    (%eax), %eax
        movl    %eax, -4(%ebp)
        movl    12(%ebp), %eax
        movl    (%eax), %edx
        movl    8(%ebp), %eax
        movl    %edx, (%eax)
        movl    12(%ebp), %edx
        movl    -4(%ebp), %eax
        movl    %eax, (%edx)
        leave
        ret
        .size   swap, .-swap
        .ident  "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
        .section        .note.GNU-stack,"",@progbits

왜 16이어야 하는지 잘 모르겠습니다. 4로도 충분할텐데요..
왜 일까요 ??
prio의 이미지

gcc는 최적화를 하지 않으면 실제 사용 여부에 관계 없이
모든 automatic variable에 대한 공간을 확보해 놓는 듯 합니다.

a, b, t 모두 4 byte 씩 12 byte 인데,
8-byte alignment 에 의해 16 byte를 할당하는 것 같네요.

최적화 옵션을 주고 컴파일 하시면 아마 스택을 전혀 사용하지 않는 코드를 생성할 겁니다.

hongwoo의 이미지

O1, O2등으로 해봤는데., 전혀 다른 asm 코드들이 나오네요.
local variable 에 대한 공간이 16byte에 맞춰지는거 같습니다. 매개변수는 스택에 쌓이구요.
감사합니다 ~

void shift(int *a, int *b, int *c, int*d, int *e) {
    int t = *a;
    int g, h, j;
    *a = *b;
    *b = *c;
    *c = *d;
    *d = *e;
    *e = t;
}
 
...
shift:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $16, %esp
    movl    8(%ebp), %eax
    movl    (%eax), %eax
...

-----------------------------
in the real-time scheduler !

prio의 이미지

웁쓰. x86에서 파라미터는 무조건 스택으로 넘기는 건데 깜빡했습니다.
레지스터 패싱이라고 생각하고 매개변수도 쳤네요. ^^;;

x86에서 스택 프레임은 16-byte alignment 가 맞네요.