2012-05-05 18 views
29

Tôi đã đọc rằng nó được sử dụng cho các chức năng thực hiện các cuộc gọi hệ thống trong Linux. Ví dụ:Công cụ sửa đổi 'asmlinkage' có nghĩa là gì?

asmlinkage long sys_getjiffies(void) 
{ 
    return (long)get_jiffies_64(); 
} 

và nó cho trình biên dịch chuyển tất cả các đối số hàm trên ngăn xếp. Nhưng đó không phải là trường hợp? Đối số chức năng thường được truyền bằng cách đẩy chúng vào ngăn xếp chỉ. Hay là chúng ta đang đề cập đến các đối số hàm truyền qua các thanh ghi ở đây?

+3

Lưu ý rằng các tham số đầu tiên của các hàm nhân Linux được chuyển vào sổ đăng ký trên x86 theo mặc định. Trên x86-32, 3 tham số đầu tiên được truyền trong '% eax','% edx' và '% ecx', theo thứ tự đó, các tham số còn lại sẽ được xếp chồng lên nhau. Các hàm với các danh sách đối số biến là một ngoại lệ, chúng nhận được tất cả các đối số của chúng trên stack trên x86-32. Trên x86-64, 6 tham số đầu tiên được chuyển trong '% rdi','% rsi', '% rdx','% rcx', '% r8','% r9' (ngay cả đối với các hàm có varargs), theo thứ tự đó, phần còn lại - trên ngăn xếp. Hệ thống gọi theo các quy ước khác nhau. – Eugene

+0

(tiếp theo) Như @dirkgently lưu ý, 'asmlinkage' là một cách để ghi đè lên các quy ước mặc định trên thông số đi qua. Xem thêm mô tả chi tiết về các quy ước gọi khác nhau trong sách hướng dẫn của Agner Fog (http://www.agner.org/optimize/calling_conventions.pdf). – Eugene

+0

Có một giải thích tốt về Quora: [https://www.quora.com/Linux-Kernel/What-does-asmlinkage-mean-in-the-definition-of-system-calls](https://www .quora.com/Linux-Kernel/What-does-asmlinkage-mean-in-the-definition-of-system-calls). –

Trả lời

26

Có một FAQ:

Thẻ asmlinkage là một chuyện khác mà chúng ta nên quan sát về chức năng đơn giản này. Đây là #define cho phép thuật gcc nào đó cho trình biên dịch biết rằng hàm không nên tìm bất kỳ đối số nào trong sổ đăng ký (tối ưu hóa chung), nhưng chỉ trên ngăn xếp của CPU. Nhớ lại xác nhận trước đó của chúng tôi rằng system_call tiêu thụ đối số đầu tiên , số cuộc gọi hệ thống và cho phép tối đa bốn đối số được chuyển cùng với cuộc gọi hệ thống thực. system_call đạt được điều này chỉ đơn giản bằng cách để lại các đối số khác của nó (được chuyển cho nó trong sổ đăng ký) trên ngăn xếp. Tất cả các cuộc gọi hệ thống đều được đánh dấu bằng thẻ asmlinkage, vì vậy tất cả chúng đều nhìn vào chồng đối số. Tất nhiên, trong trường hợp của sys_ni_syscall, điều này không tạo ra bất kỳ sự khác biệt nào, vì sys_ni_syscall không nhận bất kỳ đối số nào, nhưng đây là sự cố cho hầu hết các cuộc gọi hệ thống khác. Và, bởi vì bạn sẽ thấy asmlinkage trước nhiều chức năng khác, tôi nghĩ bạn nên biết nó là gì.

Nó cũng được sử dụng để cho phép gọi một hàm từ tệp lắp ráp.

+6

Lý do là dù sao hạt nhân cần phải lưu tất cả các thanh ghi vào ngăn xếp (để khôi phục môi trường trước khi trở về không gian người dùng) khi xử lý các yêu cầu gọi hệ thống từ không gian người dùng, vì vậy sau đó các tham số có sẵn trên ngăn xếp. Tức là, nó không cần thêm nỗ lực. source: http://stackoverflow.com/questions/10060168/is-asmlinkage-required-for-a-c-function-to-be-called-from-assembly – kumar

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