2013-12-11 17 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 

Đoạn mã trên đại diện cho một phần của một dự án lớn mà tôi đang làm việc. Tôi đang cố gắng để đảo ngược mã này vào C tương đương nhưng tôi gặp khó khăn trong việc hiểu làm thế nào malloc hoạt động.Chính xác những gì _malloc làm trong lắp ráp?

Tôi tính 8 byte sẽ là kích thước của bộ nhớ được cấp phát; tuy nhiên, tôi không chắc chắn về dòng này.

mov  eax, [esp+2ch] 

malloc làm gì để phát?

Hơn nữa, đây có phải là mã C tương đương không?

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

Trả lời

14

Hàm malloc() sẽ cấp phát một khối bộ nhớ là size byte lớn. Nếu bộ nhớ được yêu cầu có thể được cấp phát một con trỏ được trả về đầu khối bộ nhớ.

Lưu ý: nội dung của khối nhận được của bộ nhớ không được khởi tạo.

Cú pháp của malloc():

void * malloc (size_t size);

Tham số:

Kích thước của khối nhớ trong byte.

giá trị Return:

Nếu yêu cầu thành công sau đó một con trỏ tới khối nhớ được trả về. Nếu chức năng không phân bổ khối yêu cầu của bộ nhớ, một NULL được trả về, NULL cũng có thể được trả về bởi một cuộc gọi thành công đến malloc() với kích thước bằng không.

Như đã nêu trong this CS 301 lecture by Dr. Lawlor:

Calling Malloc từ hội Ngôn ngữ

Đó là một chức năng khá đơn giản: vượt qua số byte bạn muốn như thông số duy nhất, trong RDI. "gọi malloc." Bạn sẽ lấy lại một con trỏ tới các byte được phân bổ được trả về trong rax. Để dọn sạch không gian sau đó, hãy sao chép con trỏ qua đến rdi và "gọi miễn phí" (Tôi đang để lại ngoài miễn phí bên dưới, vì bạn cần ngăn xếp để thực hiện việc đó đúng cách).

Dưới đây là ví dụ hoàn chỉnh về truy cập bộ nhớ lắp ráp. Tôi gọi malloc đến nhận được 40 byte dung lượng. malloc trả về địa chỉ xuất phát của không gian trong rax (phiên bản 64 bit của eax). Đó là, đăng ký rax hoạt động như một con trỏ.sau đó tôi có thể đọc và viết từ chỉ đến bộ nhớ bằng cách sử dụng cú pháp lắp ráp khung thông thường:

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 

Thay vì sao chép qua thanh ghi ecx, bạn có thể xác định bạn muốn có một 32-bit bộ nhớ ghi và đọc bằng "DWORD" ở trước dấu ngoặc, như thế này:

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 

cho malloc trong lắp ráp language..see liên kết này malloc

+2

x84 _64 và x86 có các quy ước gọi khác nhau trên các hệ điều hành khác nhau, vì vậy câu trả lời này chỉ liên quan đến tiếp tuyến. Ví dụ, trong tình huống của OP, các đối số được truyền rõ ràng trên ngăn xếp, và không phải trong sổ đăng ký. –

+2

Tại sao bạn lại nói về x86_64? –

Các vấn đề liên quan