2012-01-17 39 views
39

tôi thấy một số x86, lắp ráp trong nguồn Qt của:Lệnh "khóa" có nghĩa là gì trong lắp ráp x86?

q_atomic_increment: 
    movl 4(%esp), %ecx 
    lock 
    incl (%ecx) 
    mov $0,%eax 
    setne %al 
    ret 

    .align 4,0x90 
    .type q_atomic_increment,@function 
    .size q_atomic_increment,.-q_atomic_increment 
  1. Từ Googling, tôi biết lock hướng dẫn sẽ làm cho CPU để khóa xe buýt, nhưng tôi không biết khi nào CPU giải phóng xe buýt?

  2. Giới thiệu về toàn bộ mã trên, tôi không hiểu cách mã này triển khai Add như thế nào?

+8

Vui lòng xem http://stackoverflow.com/a/3339380/856777 – Lucian

+0

liên quan: câu trả lời của tôi trên [Có thể num ++ là nguyên tử cho 'int num'?] (Https://stackoverflow.com/questions/39393850/can -num-be-atomic-for-int-num) giải thích nguyên tử trên x86, và chính xác tiền tố 'lock' là gì, và điều gì sẽ xảy ra nếu không có nó. –

Trả lời

64
  1. LOCK không phải là hướng dẫn: đó là tiền tố hướng dẫn áp dụng cho hướng dẫn sau. Hướng dẫn đó phải là thứ có chức năng đọc-sửa-ghi trên bộ nhớ (INC, XCHG, CMPXCHG, v.v.) --- trong trường hợp này là hướng dẫn incl (%ecx)inc đặt lại từ l từ tại địa chỉ được giữ trong thanh ghi ecx .

    Tiền tố LOCK đảm bảo rằng CPU có quyền sở hữu độc quyền của dòng bộ nhớ cache phù hợp trong suốt thời gian hoạt động và cung cấp một số đảm bảo đặt hàng bổ sung. Điều này có thể đạt được bằng cách xác nhận một khóa xe buýt, nhưng CPU sẽ tránh điều này nếu có thể. Nếu xe buýt bị khóa thì nó chỉ trong khoảng thời gian của lệnh bị khóa.

  2. Mã này sao chép địa chỉ của biến được tăng lên ra khỏi ngăn xếp vào ecx đăng ký, sau đó nó lock incl (%ecx) để nguyên tử tăng biến bằng 1. Hai hướng dẫn tiếp theo thiết lập eax đăng ký (mà giữ giá trị trả về từ hàm này đến 0 nếu giá trị mới của biến là 0 và 1 giá trị khác. Hoạt động này là số tăng , không phải là thêm (do đó tên).

+0

Vì vậy, các instuction "mov $ 0,% eax" có vẻ dư thừa? – gemfield

+4

@gemfield: Không, 'MOV' đặt tất cả' EAX' thành 0. 'SETNE' chỉ thay đổi byte thấp. Không có 'MOV', 3 byte cao của' EAX' sẽ chứa các giá trị còn lại ngẫu nhiên từ các hoạt động trước đó, do đó giá trị trả về sẽ không chính xác. –

+0

Cảm ơn rất nhiều – gemfield

10

Từ google, tôi biết hướng dẫn khóa sẽ gây cpu khóa xe buýt, nhưng tôi không biết khi nào cpu phóng xe buýt?

LOCK là một tiền tố hướng dẫn, do đó nó chỉ áp dụng cho các hướng dẫn sau đây, nguồn không làm cho nó rất rõ ràng ở đây nhưng các hướng dẫn thực sự là LOCK INC. Vì vậy, các xe buýt bị khóa cho thặng dư, sau đó mở khóa

Về toàn bộ mã trên, tôi không hiểu tại sao các mã thực hiện các Thêm?

Họ không thực hiện một Add, họ thực hiện một tăng, cùng với một dấu hiệu cho thấy sự trở lại nếu giá trị cũ là 0. Một sự bổ sung sẽ sử dụng LOCK XADD (tuy nhiên, cửa sổ InterlockedIncrement/Decrement cũng thực hiện với LOCK XADD).

+0

Cảm ơn! Sau đó, đăng ký lưu trữ giá trị của giá trị trả về của hàm (q_atomic_increment)? – gemfield

+1

giá trị trả lại được lưu trữ trong% eax – nos

+0

Vì vậy, mã: "return q_atomic_increment (& _ q_value)! = 0" là để kiểm tra xem% eax có bằng không không? – gemfield

10

Điều bạn có thể không hiểu là mã micro cần thiết để tăng giá trị yêu cầu chúng tôi đọc trước giá trị cũ.

Từ khóa khóa buộc nhiều hướng dẫn vi mô thực sự xuất hiện để hoạt động một cách nguyên tử.

Nếu bạn có 2 chủ đề cố gắng tăng cùng một biến và cả hai đều đọc cùng một giá trị gốc cùng một lúc thì cả hai đều tăng lên cùng một giá trị và cả hai đều ghi cùng giá trị.

Thay vì có biến tăng gấp hai lần, đó là kỳ vọng điển hình, bạn sẽ tăng biến một lần.

Từ khóa khóa ngăn điều này xảy ra.

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