2013-12-11 18 views
12
public main 
main proc near 
push ebp 
mov  ebp, esp 
and  esp, 0FFFFFFF0h 
sub  esp, 30h 
mov  dword ptr [esp], 8 ; size 
call _malloc 
mov  [esp+2Ch], eax 
mov  dword ptr [esp+4], 4 
mov  eax, [esp+2Ch] 
mov  [esp], eax 
call __start 

Il codice sopra rappresenta una parte di un grande progetto su cui sto lavorando. Sto cercando di invertire questo codice in equivalente C, ma ho difficoltà a capire come funziona malloc.Che cosa fa esattamente _malloc in assembly?

Sto calcolando 8 byte sarebbe la dimensione della memoria allocata; tuttavia, non sono sicuro di questa linea.

mov  eax, [esp+2ch] 

Che cosa fa malloc a eax?

Inoltre questo sarebbe equivalente al codice C?

int main(void) 
{ 
int *ptr1; 
ptr1 = (int *)malloc(sizeof(8)); 
*ptr1 = 4; 
__start(*ptr1); 

risposta

14

La funzione malloc() alloca un blocco di memoria che è size byte grande. Se è possibile allocare la memoria richiesta, viene restituito un puntatore all'inizio del blocco di memoria.

Nota: il contenuto del blocco di memoria ricevuto non è inizializzato.

Sintassi di malloc():

void * malloc (size_t size);

Parametri:

dimensione del blocco di memoria in byte.

Valore restituito:

Se la richiesta è successo, allora un puntatore al blocco di memoria viene restituita. Se la funzione non è riuscita ad allocare il blocco di memoria richiesto, viene restituito un valore NULL, NULL può anche essere restituito con una chiamata riuscita a malloc() con una dimensione pari a zero.

Come indicato nel this CS 301 lecture by Dr. Lawlor:

Calling Malloc da Assembly Language

E 'una funzione molto semplice: passare il numero di BYTE si desidera come l'unico parametro, in RDI. "call malloc". Riceverete un puntatore sui byte allocati restituiti in rax. Per ripulire lo spazio in seguito, copia il puntatore su rdi e "Chiama gratis" (sto lasciando libero il qui sotto, perché hai bisogno che lo stack lo faccia correttamente).

Ecco un esempio completo di accesso alla memoria dell'assieme. Chiamo malloc a e ottengo 40 byte di spazio. malloc restituisce l'indirizzo iniziale di questo spazio in rax (la versione a 64 bit di eax). Cioè, il registro rax si comporta come un puntatore.Posso quindi leggere e scrivere dal puntato a memoria utilizzando la solita sintassi staffa di montaggio:

mov edi, 40; malloc's first (and only) parameter: number of bytes to allocate 
extern malloc 
call malloc 
; on return, rax points to our newly-allocated memory 
mov ecx,7; set up a constant 
mov [rax],ecx; write it into memory 
mov edx,[rax]; read it back from memory 
mov eax,edx; copy into return value register 
ret 

Invece di copiare tramite il registro ECX, è possibile specificare che si desidera una scrittura in memoria a 32 bit e leggere usando "DWORD" davanti alle staffe, come questo:

mov edi, 40; malloc's first (and only) parameter: number of bytes to allocate 
extern malloc 
call malloc 
; on return, rax points to our newly-allocated memory 
mov DWORD [rax],7; write constant into memory 
mov eax,DWORD [rax]; read it back from memory 
ret 

per malloc in assemblea language..see questo link malloc

+2

x84 _64 e x86 hanno diverse convenzioni di chiamata su vari SO, quindi questa risposta è solo correlata tangenzialmente. Ad esempio, nella situazione dell'OP, gli argomenti vengono chiaramente passati nello stack e non in un registro. –

+2

Perché stai parlando di x86_64? –

Problemi correlati