Premetto:
Come compilatore C e C++ utilizzo CodeBlock che è un compilatore free e open source ottimo. Quest'anticipazione è di dovere perché dipendentemente dal tipo di compilatore utilizzato può variare la sintassi del codice per quanto riguarda l'Inline Assembly (ho riscontrato problemi in passato).
Il codice da te postato è il seguente:
Codice:
#include <stdio.h>
unsigned long get_sp()
{
unsigned long stp;
__asm
{
mov eax, esp
}
}
void main(void)
{
printf("\n0x%x", get_sp());
}
Visto che uso un compilatore che adotta la sintassi AT&T per le istruzioni inline-assembly ho dovuto convertire:
[mov eax, esp] in [movl %esp, %eax] che sono praticamente la stessa cosa.
Il codice risultante, adattato al mio compilatore (che usa "(" al posto di "{" e la sintax AT&T) è il seguente:
Codice:
#include <stdio.h>
unsigned long get_sp()
{
asm
(
"movl %esp, %eax;"
);
}
void main(void)
{
printf("\n0x%x", get_sp());
}
Puoi notare che ho rimosso la variabile unsigned long stp che hai dichiarato all'interno della procedura get_sp() perché non viene utilizzata.
Dato che il codice sul mio compilatore funziona correttamente suppongo che i tuoi problemi siano legati al compilatore che hai adottato.
Non riesco poi a capire questi discorsi che avete fatto riguardo il prendere prima o dopo il valore del registro ESP, a quale scopo?
c'è da dire che funziona anche il seguente codice che evita di chiamare procedure e quindi di fare push superflue prima di prendere il valore di esp, il metodo consiste come passare il contenuto di esp in eax e poi storarlo in una variabile globale (limitazione, se non mi sbaglio, di ASM-inline su code-block):
Codice:
#include <stdio.h>
unsigned long regesp;
void main(void)
{
asm
(
"movl %esp, %eax;"
"movl %eax, _regesp;"
);
printf("\n0x%x", regesp);
}
Quest'ultimo codice stampa a video un diverso valore dello stack pointer perché non viene eseguita la procedura get_sp().
Ciao ciao.