2010-11-04 25 views
7

Tôi đang đọc "Hệ thống máy tính: Phối cảnh lập trình viên", chương 3 giải thích hướng dẫn mov và giải thích cho một cuốn sách gây nhầm lẫn cho tôi.hướng dẫn và đăng ký mov - nhầm lẫn!

cho một chức năng (trang 142 1 của edition) mã

int exchange(int *xp, int y) 
{ 
    int x = *xp; 
    *xp = y; 
    return x; 
} 

hội của cơ quan chức năng của

movl 8(%ebp), %eax //Get xp 
movl 12(%ebp), %edx //Get y 
movl (%eax), %ecx //Get x at *xp 
movl %edx, (%eax) //Store y at *xp 
movl %ecx, %eax  //Set x as return value 

gì confuses me, là những gì đang xảy ra phải được lưu trữ, và nơi
Đây là cách tôi hiểu điều này:

movl 8(%ebp), %eax //Get xp 

Chuyển động CPU +8 byte lên ngăn xếp (từ con trỏ khung %ebp), lấy giá trị được lưu trữ tại vị trí đó và lưu trữ giá trị này tại thanh ghi %eax (để nhấn mạnh - lưu trữ giá trị, không phải địa chỉ)

Tôi đúng? Cảm ơn!

Trả lời

9

Vâng, có vẻ như bạn đã hiểu đúng. IMHO, cú pháp AT & T 8(%ebp) ít trực quan hơn Intel [ebp+8] rõ ràng hơn. Các dấu ngoặc cho thấy rằng bạn đang sử dụng giá trị tại địa chỉ trong sổ đăng ký và số đó là giá trị bù trừ từ địa chỉ mà bạn thực sự muốn.

+0

RẤT đúng ...... – ruslik

+1

Vì vậy, nói cách khác, bởi vì 'cửa hàng% ebp' con trỏ, chúng ta sử dụng dấu ngoặc xung quanh tên gọi của nó, để xác định rằng chúng tôi đang nhận được giá trị được lưu trữ + 8bytes đi từ '% ebp'. Trong trường hợp này, '8 (% ebp)' chứa con trỏ '* xp'. Sau đó, trong dòng 'movl (% eax),% ecx' chúng ta là dereferencing' xp' giống như cách chúng ta đã làm trong dòng đầu tiên của mã assembly – newprint

+0

Bây giờ, mọi thứ đều thẳng ra. Dấu ngoặc đơn là nguồn gốc của sự nhầm lẫn! Cảm ơn ! – newprint

2

Vâng, đây là sử dụng AT & T cú pháp, trong đó có dạng:

instruction  source, dest 

Intel lắp ráp là the opposite order.

Bạn cũng đúng về việc 8(%ebp) di chuyển 8 byte lên từ con trỏ khung. Lý do nó di chuyển 8 byte, cụ thể, là bởi vì các tham số được đẩy vào ngăn xếp theo thứ tự ngược lại ("phải" sang "trái" khi nhìn vào một cuộc gọi chức năng điển hình). Do đó, y được đẩy trước tiên, sau đó xp và cuối cùng là địa chỉ trả về của hàm người gọi (đó là lý do tại sao bạn di chuyển 8 byte thay vì 4).

1

Bạn cần hiểu khung ngăn xếp là gì. Tìm hiểu chính xác các hướng dẫn chính xác của pushpop. Trước mã đó có một số

push y_val 
    push xp_ptr 
    call exchange 
.cont  
... 
.exchange 
    push ebp 
    mov ebp, esp 
// .. rest of code 
// stack frame: 
    old_ebp_val ; [ebp] points here 
    .cont  ; [ebp + 4] 
    xp_ptr  ; [ebp + 8] 
    y_val 
+0

Câu hỏi của tôi không phải là về ngăn xếp, thậm chí cả ngăn xếp suy nghĩ cũng có liên quan. Đó là về các giá trị được lưu trữ trong đăng ký và bộ nhớ – newprint

+1

@user Hãy thử thực hiện RTTI trong tâm trí. Luôn theo dõi các loại giá trị. – ruslik