2. Variabile locale

Dorim să înțelegem rolul variabilelor locale și să învățăm cum le putem folosi.

Reprezentare

Vom scrie programe în C pe care le vom compila folosind consola MINGW pentru a putea observa assembly-ul generat.

Deschideți consola MINGW. (C:\MinGW\msys\1.0\msys.bat)

test.c
    #include <stdio.h>
 
    int main(void)
    {
    	int my_g = 1000;
    	return 0;
    }

Pentru generarea fișierului assembly folosiți: gcc -S -O0 -masm=intel -o test.asm test.c. Observați următoarea secțiune:

	mov	DWORD PTR [ebp-4], 1000

Deoarece variabilele locale se alocă pe stivă, accesul se face prin folosirea offset-urilor față de registrul ebp.

Modificăm programul astfel:

test.c
    #include <stdio.h>
 
    int main(void)
    {
    	int my_g = 1000;
		int my_f = 900;
 
		my_g++;
		my_f--;
 
		my_f += my_g;
 
    	return 0;
    }

Care va genera următoare secvență assembly:

	# Se inițializează variabila my_g
	mov	DWORD PTR [ebp-4], 1000
	# Se inițializează variabila my_f
	mov	DWORD PTR [ebp-8], 900
	# Se încarcă adresa variabilei my_g în eax
	lea	eax, [ebp-4]
	# Se incrementează valoarea de la adresa reprezentată de eax
	inc	DWORD PTR [eax]
	# Se încarcă adresa variabilei my_f în eax
	lea	eax, [ebp-8]
	# Se decrementează valoarea de la adresa reprezentată de eax
	dec	DWORD PTR [eax]
	# Se inițializează registrul edx cu valoarea variabilei my_g
	mov	edx, DWORD PTR [ebp-4]
	# Se încarcă adresa variabilei my_f în eax
	lea	eax, [ebp-8]
	# Se adună la valoarea de la adresa reprezentată de eax, valoarea edx
	add	DWORD PTR [eax], edx

Observăm că variabila my_g se află la ebp-4, în timp ce my_f se află la ebp-8. Cele două variabile au fost așezate pe stivă consecutiv, my_f aflându-se la o adresă inferioară, deci deasupra lui my_g în stivă.

Putem observa că variabilele locale nu sunt obligatoriu consecutive. Compilatorul uneori face alinieri și lasă unele zone de memorie nefolosite pentru a optimiza timpul la run-time.

C assembly
    #include <stdio.h>
 
    int main(void)
    {
    	int my_g = 1000;
		char char_g = '4';
		int my_f = 900;
 
    	return 0;
    }
	mov	DWORD PTR [ebp-4], 1000
	mov	BYTE PTR [ebp-5], 52
	mov	DWORD PTR [ebp-12], 900

De asemenea, variabilele nu se vor afla în mod obligatoriu în ordinea definită în limbajul C:

C assembly -O0 assembly -O3
		char a1 = 1;
		int a2 = 2;
		char a3 = 3;
	mov	BYTE PTR [ebp-1], 1
	mov	DWORD PTR [ebp-8], 2
	mov	BYTE PTR [ebp-9], 3
	mov	ecx, 3
	mov	edx, 2
	mov	DWORD PTR [esp+12], ecx
	mov	eax, 1
	mov	DWORD PTR [esp+8], edx
	mov	DWORD PTR [esp+4], eax

Observăm că în cea de-a doua coloană, ordinea variabilelor de jos în sus este a3, a2 și a1. În cea de-a treia coloană, ordinea a1, a2, a3.

Compilatorul poate aloca variabilele locale în orice ordine. În exemplul de mai sus ar fi putut să pună chiar și ordinea a1, a3 și a2.

ihs/cursuri/capitol-07/demo/02.txt · Last modified: 2021/09/20 18:05 (external edit)
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0