Struktura assembler

AU
  • Rejestracja:około 13 lat
  • Ostatnio:prawie 12 lat
  • Postów:21
0

Witam napisałam testowy program reprezentujący listę w języku C, i dziwi mnie rozkład danej struktury w pamięci podczas przekazania jej do parametru metody napisanej w assemblerze. A mianowicie, zacznijmy od kodu:
Kod C

Kopiuj
struct element{
int liczba;
char nazwa;
struct element *nast;
struct element *poprz;
};

int dodaj(int liczba, char nazwa){
struct element *nowy; 

if((nowy=(struct element *)malloc(sizeof(struct element)))==NULL)
return 1;

nowy->liczba=liczba;
nowy->nazwa=nazwa;
if(pierwszy==NULL){ 
nowy->nast=NULL; 
nowy->poprz=NULL; 
pierwszy=nowy; 
ostatni=nowy; 
} else {
nowy->nast=NULL; 
nowy->poprz=ostatni;
ostatni->nast=nowy; 
ostatni=nowy; 
}
return 0;
}

int main()
{
	dodaj(2,'t');
	dodaj(5,'k');
	dodaj(3,'p');
	dodaj(4,'d');
	funkcja(pierwszy);
	return 0;
} 

Kod Assembler

Kopiuj
 
.686
.model flat
public _funkcja
.code

_funkcja PROC
push ebp
mov ebp,esp
mov ebx,[ebp+8] ;adres początku struktury
mov ecx,[ebx] ;zczytanie pierwszego elementu czyli liczby int ktora zajmuje 4 bajty, tutaj się wszystko zgadza
mov dl,[ebx+4] ;położone 4 bajty dalej obszar znaku char, tez się zgadza i w dl mamy znak

mov ecx,[ebx+5] ;tutaj już sie nie zgadza chce pobrać wskaźnik na kolejny element struktury poprzedni char zajmuje 1 bajt wiec
mov edx,[ecx]    ;stad wnioskuje ze kolenjy element struktury(czyli adres następnego elementu) powinien znajdować się o 1 dalej
                       ;czyli o adresie [ebx+5], jednak zauważyłam ze ten adres znajduje się pod [ebx+8] czyli wskazywałoby na to, że
pop ebp             ;ten znak zaisany jest na 4 bajtach, i moje pytanie jest takie, dlaczego tak się dzieje, czy może coś przeoczyłam?
RET
              
_funkcja ENDP
END

A konkretne pytanie zawarte jest w komentarzach kodu do assemblera. Z góry dziękuje za pomoc.

1

Struktura jest z wyrównaniem pól, za tym bajtem będą 3 kolejne wyrównania dla kolejnego inta. Albo popraw offsety albo ustaw wyrównanie na 1:

Kopiuj
/* zapamiętaj poprzednią wartość i ustaw aktualną na 1 */
#pragma pack(push, 1)

struct element{
int liczba;
char nazwa;
struct element *nast;
struct element *poprz;
};

/* przywróć poprzednią wartość*/
#pragma pack(pop)
AU
  • Rejestracja:około 13 lat
  • Ostatnio:prawie 12 lat
  • Postów:21
0

Dziękuję, nie wiedziałam o tym. Czyli domyślnie, zawsze dla struktury kompilator stosuje wyrównywanie?

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Wrocław
  • Postów:13042
0

Zapewne tak; podobnie z resztą jest np.w umieszczaniu "normalnych" zmiennych czy zmiennych klas w pamięci - także jest to wyrównywane.


0

"To zależy", od kompilatora, zarchitektury, systemu operacyjnego itd. Generalnie jeśli korzystasz z IDE to każde poważniejsze pozwala w wygodny sposób to kontrolować, takie rzeczy muszą być w opcjach projektu.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.