osdev.labedz.org

Ramka stosu procedury w języku C

Standardem przyjętym w języku C jest przekazywanie argumentów wejściowych za pomocą stosu programowego, a argumentów wyjściowych za pomocą rejestrów procesora (i czasami stosu). Argumenty funkcji są umieszczane w odwrotnym porządku - pierwszy argument funkcji znajduje się zawsze na szczycie stosu. Dzięki takiemu rozwiązaniu istnieje możliwość przekazywania dowolnej, nieokreślonej z góry ilości argumentów. W takim przypadku pierwszy z nich najczęściej określa liczbę przekazanych do procedury parametrów.

Ramka stosu wywołania procedury w języku C
Rys. Ramka stosu wywołania procedury w języku C

Standardowo, w systemach 32-bitowych, przyjmuje się, że każdy argument mniejszy od słowa maszynowego zajmuje na stosie całe słowo. Dzięki temu programista nie musi się martwić o wielkości argumentów mniejszych od słowa maszynowego, co powoduje spore ułatwienie zaimplementowania komunikacji procedur napisanych w językach różnych poziomów.

W języku C przyjmuje się, że procedura, która wywołuje inną procedurę wraz z przekazaniem argumentów, po powrocie z niej, usuwa te argumenty ze stosu. Dzieje się tak dlatego, ponieważ procedura wywołująca wie ile argumentów zostało umieszczonych na stosie, natomiast wywoływana może się jedynie opierać na przekazanej liczbie argumentów, która to nie zawsze musi być umieszczona.

Po przekazaniu kontroli do nowej procedury, wartość rejestru EBP zostaje ustawiona na adres pierwszej zmiennej lokalnej procedury (lub na adres następny po miejscu gdzie jest przechowywana stara wartość EBP). Pierwszy argument znajduje się pod adresem [EBP + 12], gdzie liczba 12 oznacza wielkość adresu powrotu plus wielkość zmiennej przechowującej starą wartość EBP.