# Stos i C

## Paladyn

Mam problem z GCC i kompilacją.

Na przykład funkcja:

int function(int a, int b)

{

char buffer[10];

int number;

}

powinna mieć ramkę na stosie w takiej kolejności:

number

buffer

ESP

EIP

a

b

ale mi wychodzi taka:

buffer

number

ESP

EIP

a

b

niezależnie od tego czy deklarowana jest zmienna numer czy buffer odkładana jest na stos zawsze ta kolejność: buffer number ... itd.

Może problem stanowią flagi CFLAGS jakie mam ustawione.

A chodzi mi o to, że za każdym razem przy przepełnieniu buforu zapisywana jest zmienna int number bo adres buffer jest zawsze przed int, a prawidłowo tak nie powinno być!

Na Ubuntu mi działa ta funkcja bez problemu i ramka stosu jest odkładana poprawnie, ale na Gentoo działa mi źle.

----------

## joi_

kompilator ma pełne prawo do zmiany kolejności odkładania zmiennych na stosie i chyba nic z tym zrobić się nie da

możesz za to stworzyć strukturę z tymi 2 polami i umieścić ją na stosie - kompilator powinien zachować kolejność pól, bo jest ona częścią interfejsu binarnego struktury...

----------

## Paladyn

No właśnie o to chodzi, że funkcja wywoływana jest odkładana na stos w odpowiedniej kolejności.

Jeżeli dodam kompilację z opcją -02 to nie przepełnia mi bufora, ale nie mogę się odwołać w programie gdb do adresu zmiennej int numer.

Jeżeli kompiluje prostym sposobem gcc -g program.c to do adresów mogę się dostać w gdb, ale zawsze buffor jest o niższym adresem niż zmienna numer co powoduje nadpisanie zmiennej numer jak przepełnie tablicę znaków buffer.

Ale jeżeli jest w funkcji tablica znaków zadeklarowana jako 1, a po niej zmienna int numer to powinno wszystko działać jak należy, bo jak wiadomo zmienne lokalne są odkładane w kolejności w takiej jakiej zostały zadeklarowane. 

// Dziwne jest to, że dodam opcję -O2 i kompiluje inaczej, a bez opcji -O2 inaczej mimo iż mam w CFLAGS ustawione O2  :Confused: 

----------

## Raku

 *Paladyn wrote:*   

> // Dziwne jest to, że dodam opcję -O2 i kompiluje inaczej, a bez opcji -O2 inaczej mimo iż mam w CFLAGS ustawione O2 

 

gcc nie wie, co to CFLAGS.

----------

## mziab

Poza tym C(XX)FLAGS jest dostępne jako zmienna środowiskowa tylko podczas działania emerge. Dopiero wtedy jest parsowana zawartość /etc/make.conf.

----------

## dziadu

A tak swoją drogą, czy przepełnianie buforu nie jest świadectwem źle napisanego programu? Gdziekolwiek by ta tablica nie była, nie powinieneś wykraczać poza jej zakres.Last edited by dziadu on Sun Feb 15, 2009 4:29 pm; edited 1 time in total

----------

## Paladyn

 *dziadu wrote:*   

> A tak swoją drogą, czy przepełnianie buforu nie jest świadectwem źle napisanego programu? Gdziekolwiek by ta tablica nie była, nie powinieneś wykraczać poza jej zakres.

 

Działanie tego programu jest celowe tylko rezultaty są inne niż przewiduje lektura, którą czytam  :Smile: 

----------

## chomzee

Łatwo zauważyć, że kod

```
int function(int a, int b)

{

char buffer[10];

int number;

/* costam */

}
```

z punktu widzenia języka c jest identyczny z

```
int function(int a, int b)

{

int number;

char buffer[10];

/* costam */

}
```

Bo co za różnica, która zmienna jest zadeklarowana jako pierwsza? I tak zmienne lokalne deklaruje się na początku bloku. Widocznie kompilator stwierdza, że może sobie pozwolić na dowolność. Nie mam pojęcia, czy takie rzeczy, jak kolejność odkładania zmiennych na stos jest w jakikolwiek sposób ustandaryzowana.

A co do CFLAGS, to jak wcześniej powiedziano, musisz explicite powiedzieć kompilatorowi czego chcesz. Na przykład:

```
$ source /etc/make.conf

$ gcc $CFLAGS -o program program.c
```

----------

## 13Homer

 *chomzee wrote:*   

> Bo co za różnica, która zmienna jest zadeklarowana jako pierwsza?

 

Nieuważnie czytasz posty. W tym wypadku wymagane jest, aby zmienne były odkładane na stosie w określonej kolejności.

----------

## ucho

http://stackoverflow.com/questions/238441/can-a-c-compiler-rearrange-stack-variables

----------

## Paladyn

Dzieki ucho za linka! Parę moich problemów zostało rozwiąnych  :Smile: 

----------

