Stack Erweiterung bei Arrays größer als erwartet!



  • Hallo zusammen,

    Folgendes mini Programm:

    void func(int zap, int za, int rap){
    	char buffer[5];
    
    }
    
    void main() {
    
    func(1,2,3);
    }
    
    function:
    	pushl	%ebp
    	movl	%esp, %ebp
    	subl	$24, %esp	// Wieso 24 Bytes Und nicht einfach 8?
    	leave
    	ret
    

    OS: Mandrake Linux 10.2
    Gcc: 3.4.3
    Das Programm wird Compiliert: gcc -S -o test.s test.c

    Nur wird der Stack auf 24 Bytes erweitert statt den erwarteten 8 Bytes. Wieso?

    Die Sache ist mir nur bei Arrays aufgefallen (egal welcher Datentyp), es wurde immer mehr
    reserviert als angegeben!

    aber:

    Wird das Array auf

    char buffer[4]
    

    reduziert, wird der Stack auch nur um 4Bytes erweitert:

    function:
    	pushl	%ebp
    	movl	%esp, %ebp
    	subl	$4, %esp  // Hier dann 4 Bytes ?
    	leave
    	ret
    

    Gruß
    Guanin



  • Und der Rest der Funktion ist gleich geblieben?



  • ja!

    nur müsste der Assembler Code eigendlich mit:

    func:
        ....
    

    beginnen und nicht mit " function: "
    Sorry mein Fehler.

    Hier mal der ganze Code inclusive main()
    für buffer[5] und buffer[10] identisch:

    .globl func
    	.type	func, @function
    func:
    	pushl	%ebp
    	movl	%esp, %ebp
    	subl	$24, %esp
    	leave
    	ret
    	.size	func, .-func
    .globl main
    	.type	main, @function
    main:
    	pushl	%ebp
    	movl	%esp, %ebp
    	subl	$8, %esp
    	andl	$-16, %esp
    	movl	$0, %eax
    	subl	%eax, %esp
    	subl	$4, %esp
    	pushl	$3
    	pushl	$2
    	pushl	$1
    	call	func
    	addl	$16, %esp
    	leave
    	ret
    	.size	main, .-main
    	.section	.note.GNU-stack,"",@progbits  //kann das Problem hiermit zusammenhängen ?
    


  • Üblicherweise dient sowas dem Alignment, also dazu dass Dinge auf dem Stack an Speicheradrsesen liegen, die durch Zahlen wie 32 oder 64 teilbar sind, dies kann manchmal zu etwas schnelleren Zugriffen führen. Warum allerdings die komische Differenz von 20...



  • Seltsamerweise ist das aber nur bei Arrays so, sobald ich:

    char buffer[5];
    
    in: 
    
    char za;
    char zb;
    char zc;
    char zd;
    char ze;
    

    aufgliedere, werden nur 8Bytes reserviert!



  • Dass für [5] und [10] gleich viel Speicher reserviert wird, glaube ich dir gern, aber das im ersten Post kann ich mir nicht ganz vorstellen. Dort behauptest du, dass er bei [4] nur 4 Bytes belegt, bei [5] aber 24 - also 20 Unterschied. Was soll das denn? Kann ich nicht glauben.



  • Vor 3 Minuten nochmals getestet:

    für den Code:

    void func(int zap, int za, int rap) {
    	char buffer[4];
    }
    
    void main() {
    
    func(1,2,3);
    }
    

    gcc -S -o test.s test.c

    in asm:

    .file	"test.c"
    	.text
    .globl func
    	.type	func, @function
    func:
    	pushl	%ebp
    	movl	%esp, %ebp
    	subl	$4, %esp   // hier 4 unten 24 
    	leave
    	ret
    	.size	func, .-func
    .globl main
    	.type	main, @function
    main:
    	pushl	%ebp
    	movl	%esp, %ebp
    	subl	$8, %esp
    	andl	$-16, %esp
    	movl	$0, %eax
    	subl	%eax, %esp
    	subl	$4, %esp
    	pushl	$3
    	pushl	$2
    	pushl	$1
    	call	func
    	addl	$16, %esp
    	leave
    	ret
    	.size	main, .-main
    	.section	.note.GNU-stack,"",@progbits
    

    abändern von test.c auf "char buffer[5]"

    void func(int zap, int za, int rap) {
    	char buffer[5];
    }
    
    void main() {
    
    func(1,2,3);
    }
    

    gcc -S -o test2.s test2.c

    in asm:

    .file	"test.c"
    	.text
    .globl func
    	.type	func, @function
    func:
    	pushl	%ebp
    	movl	%esp, %ebp
    	subl	$24, %esp        // hier 24 oben nur 4 
    	leave
    	ret
    	.size	func, .-func
    .globl main
    	.type	main, @function
    main:
    	pushl	%ebp
    	movl	%esp, %ebp
    	subl	$8, %esp
    	andl	$-16, %esp
    	movl	$0, %eax
    	subl	%eax, %esp
    	subl	$4, %esp
    	pushl	$3
    	pushl	$2
    	pushl	$1
    	call	func
    	addl	$16, %esp
    	leave
    	ret
    	.size	main, .-main
    	.section	.note.GNU-stack,"",@progbits
    

    Warum übrigens sollte für buffer[5] und buffer[10] gleich viel Speicher reserviert werden?

    gruß
    Guanin



  • Warum übrigens sollte für buffer[5] und buffer[10] gleich viel Speicher reserviert werden?

    Siehe TriPhoenix' Antwort.

    Solange du nicht mit -O2 compilierst, ist das außerdem alles ziemlich belanglos.



  • Solange du nicht mit -O2 compilierst, ist das außerdem alles ziemlich belanglos.

    Warum?


Anmelden zum Antworten