Waarom doet gcc dit bij het maken van assembler-code?

Ik ben aan het spelen met gcc -S om te begrijpen hoe geheugen en stack werken. Tijdens deze toneelstukken vond ik verschillende dingen onduidelijk voor mij. Kun je me alsjeblieft helpen om de redenen te begrijpen?

  1. When calling function sets arguments for a called one it uses mov to esp instead push. What is the advantage not using push?

  2. Function which works with its stack located arguments points to them as ebp + (N + offset) (where N is a size reserved for return address). I expect to see esp - offset which is more understandable. What is the reason to use ebp as fundamental point everywhere? I know these ones are equal but anyway?

  3. What is this magic for in the beginning of main? Why esp must be initialized in this way only?

    and    esp,0xfffffff0
    

Bedankt,

8
Dit kunnen 3 afzonderlijke vragen zijn. Hoe dan ook, het antwoord op het derde punt is de uitlijning van de stapel.
toegevoegd de auteur Mysticial, de bron

1 antwoord

Ik ga ervan uit dat u onder een 32-bits omgeving werkt omdat in een 64-bitsomgeving argumenten in registers worden doorgegeven.

Vraag 1

Misschien geef je hier een floating point-argument door. Je kunt niet direct hierop duwen, omdat de push -instructie in een 32-bits runtime 4 bytes per keer pusht, dus je zou de waarde moeten opsplitsen. Het is soms eenvoudiger om 8 af te trekken van esp en ze verplaatsen het 8-byte quadwoord naar [esp] .

vraag 2

ebp is frequently used to index the parameters and locals in stack frames in 32-bit code. This allows the offsets within frames to be fixed even as the stack pointer moves. For example consider

void f(int x) {
    int a;
    g(x, 5);
}

Als u nu alleen toegang hebt tot de inhoud van het stapelframe met esp , dan is a op [esp] , het adres van de retour is [esp + 4] en x staan ​​op [esp + 8] . Laten we nu code genereren om g aan te roepen. We moeten eerst op 5 drukken en vervolgens op x drukken. Maar na het drukken op 5 is de offset van x van esp veranderd! Dit is de reden waarom ebp wordt gebruikt. Normaal bij het invoeren van functies drukken we op de oude waarde van ebp om het op te slaan en kopiëren we vervolgens esp naar ebp . Nu kan ebp worden gebruikt om toegang te krijgen tot de inhoud van het stapelframe. Het zal niet bewegen wanneer we ons in het midden van voorbijgaande argumenten bevinden.

vraag 3

Met deze instructie en worden de laatste 4 bits van esp uitgelijnd en uitgelijnd op een 16-byte-begrenzing. Aangezien de stapel naar beneden toe groeit, is dit leuk en veilig.

7
toegevoegd
Oh my, bedankt, @drhirsch. Typen zonder na te denken. Vreselijk. Heel erg bedankt! Bewerkt.
toegevoegd de auteur Ray Toal, de bron
V3: Het geeft de laatste 4 bits een nul
toegevoegd de auteur hirschhornsalz, de bron