Các liên kết sau giải thích các quy ước gọi hệ thống x86-32 cho cả UNIX (hương vị BSD) & Linux:

http://www.int80h.org/bsdasm/#system-calls

http://www.freebsd.org/doc/en/books/developers-handbook/x86-system-calls.html

Nhưng các quy ước gọi hệ thống x86-64 trên cả UNIX & Linux là gì?

linux unix assembly x86-64 abi
chia sẻ | theo dõi

Không có “tiêu chuẩn” cho các quy ước gọi Unix. Đối với linux chắc chắn, nhưng tôi chắc chắn rằng Solaris, OpenBSD, Linux và Minix có thể có các quy ước gọi khác nhau ít nhất một chút và tất cả chúng đều là unix.

– Huỳnh Bích Ty 05:51:04 29/03/2010
2

Điều đó không hoàn toàn đúng – có một bộ UNIX ABI có sẵn cho hầu hết các loại máy, cho phép trình biên dịch C đạt được khả năng tương tác. Trình biên dịch C ++ có một vấn đề lớn hơn.

– Nguyễn Xuân Thiện 06:54:39 29/03/2010
1

Cả hai bạn đều đúng. Tôi đang tìm kiếm FreeBSD & Linux.

– Nguyễn Viết Sơn 07:19:24 29/03/2010

Tôi sẽ đánh giá cao nếu câu trả lời chứa thông tin về những gì các thanh ghi được bảo toàn trên các cuộc gọi hệ thống. Tất nhiên, con trỏ ngăn xếp là, (trừ khi thay đổi theo cách được kiểm soát trong lệnh gọi __NR_clone), nhưng những cái khác của chúng?

– Nguyễn Ðình Hợp 12:28:43 22/01/2016
AlbertvanderHorst: vâng, tôi vừa cập nhật câu trả lời wiki với các chi tiết cho 32 bit. 64 bit đã chính xác: RCx và r11 bị phá hủy do cách thức sysrethoạt động, cùng với rax được thay thế bằng giá trị trả về. Tất cả các thanh ghi khác được bảo quản trên amd64. – Tạ Thanh Quang 23:22:01 01/02/2016
thêm 1 bình luận  | 

4 trả lời 4

Hoạt động Cũ nhất Hữu ích
197

Đọc thêm cho bất kỳ chủ đề nào ở đây: Hướng dẫn dứt khoát cho các cuộc gọi hệ thống Linux

Tôi đã xác minh những thứ này bằng cách sử dụng GNU Assembler (gas) trên Linux.

Bạn đang xem: I386 là gì

Giao diện hạt nhân

x86-32 aka i386 Quy ước cuộc gọi hệ thống Linux:

Trong các tham số x86-32 cho cuộc gọi hệ thống Linux được thông qua các thanh ghi. %eaxcho syscall_number. % ebx,% ecx,% edx,% esi,% edi,% ebp được sử dụng để truyền 6 tham số cho các cuộc gọi hệ thống.

Giá trị trả về là trong %eax. Tất cả các thanh ghi khác (bao gồm EFLAGS) được bảo toàn trên int $0x80.

Tôi đã theo đoạn trích từ Hướng dẫn lắp ráp Linux nhưng tôi nghi ngờ về điều này. Nếu bất kỳ ai có thể đưa ra một ví dụ, nó sẽ là tuyệt vời.

Nếu có nhiều hơn sáu đối số, %ebxphải chứa vị trí bộ nhớ nơi lưu danh sách các đối số – nhưng đừng lo lắng về điều này bởi vì không chắc là bạn sẽ sử dụng một tòa nhà cao tầng với hơn sáu đối số.

Để biết ví dụ và đọc thêm một chút, hãy tham khảo http://www.int80h.org/bsdasm/#alternate-calling-convent . Một ví dụ khác về Hello World cho i386 Linux bằng cách sử dụng int 0x80: Phần nào trong mã lắp ráp HelloWorld này rất cần thiết nếu tôi viết chương trình này trong phần lắp ráp?

Có một cách nhanh hơn để thực hiện các cuộc gọi hệ thống 32 bit: sử dụng sysenter. Hạt nhân ánh xạ một trang bộ nhớ vào mọi tiến trình (vDSO), với phía không gian người dùng của sysenterđiệu nhảy, phải hợp tác với hạt nhân để có thể tìm thấy địa chỉ trả về. Arg để đăng ký ánh xạ giống như cho int $0x80. Thông thường bạn nên gọi vào vDSO thay vì sử dụng sysentertrực tiếp. (Xem Hướng dẫn dứt khoát cho các cuộc gọi hệ thống Linux để biết thông tin về liên kết và gọi vào vDSO, và để biết thêm thông tin về sysentervà mọi thứ khác liên quan đến các cuộc gọi hệ thống.)

x86-32 Quy ước cuộc gọi hệ thống UNIX BSD:

Các thông số được truyền vào ngăn xếp. Đẩy các tham số (tham số cuối cùng được đẩy trước) vào ngăn xếp. Sau đó đẩy thêm 32 bit dữ liệu giả (Dữ liệu không thực sự là dữ liệu giả. Tham khảo liên kết sau để biết thêm thông tin) và sau đó đưa ra hướng dẫn gọi hệ thốngint $0x80

http://www.int80h.org/bsdasm/#default-calling-convent

x86-64 Quy ước cuộc gọi hệ thống Linux:

x86-64 Mac OS X tương tự nhưng khác nhau . TODO: kiểm tra xem * BSD làm gì.

Tham khảo phần: “A.2 AMD64 Linux Kernel Conventions” của System V Application Binary Interface AMD64 Architecture Processor Bổ sung . Có thể tìm thấy các phiên bản mới nhất của psABI i386 và x86-64 System V được liên kết từ trang này trong repo của người bảo trì ABI . (Xem thêm wiki thẻ x86 để biết các liên kết ABI cập nhật và nhiều nội dung hay khác về x86 asm.)

Đây là đoạn trích từ phần này:

Các ứng dụng cấp người dùng sử dụng làm các thanh ghi số nguyên để truyền chuỗi% rdi,% rsi,% rdx,% rcx,% r8 và% r9. Giao diện kernel sử dụng% rdi,% rsi,% rdx,% r10,% r8 và% r9. Một cuộc gọi hệ thống được thực hiện thông qua syscallhướng dẫn . Điều này ghi lại % RCx và% r11 cũng như giá trị trả về% rax, nhưng các thanh ghi khác được giữ nguyên. Số lượng tòa nhà phải được thông qua trong đăng ký% rax. Các cuộc gọi hệ thống được giới hạn trong sáu đối số, không có đối số nào được truyền trực tiếp trên ngăn xếp. Trở về từ tòa nhà, đăng ký% rax chứa kết quả của cuộc gọi hệ thống. Một giá trị trong phạm vi từ -4095 đến -1 chỉ ra lỗi -errno. Chỉ các giá trị của lớp INTEGER hoặc MEM MEM class được truyền vào kernel.

Hãy nhớ điều này là từ phụ lục dành riêng cho Linux cho ABI và ngay cả đối với Linux, thông tin này không mang tính quy phạm. (Nhưng thực tế nó chính xác.)

int $0x80ABI 32 bit này có thể sử dụng được trong mã 64 bit (nhưng không được khuyến khích). Điều gì xảy ra nếu bạn sử dụng 32-bit int 0x80 Linux ABI trong mã 64 bit? Nó vẫn cắt các đầu vào của nó thành 32 bit, do đó, nó không phù hợp với các con trỏ và nó không có giá trị r8-r11.

Giao diện người dùng: chức năng gọi

x86-32 Quy ước gọi hàm:

Trong x86-32 tham số được truyền vào ngăn xếp. Tham số cuối cùng được đẩy đầu tiên vào ngăn xếp cho đến khi tất cả các tham số được thực hiện và sau đó calllệnh được thực thi. Điều này được sử dụng để gọi các hàm thư viện C (libc) trên Linux từ lắp ráp.

Xem thêm: Quá Tải (overload) Và Ngắn Mạch ( Short Circuit Là Gì

Các phiên bản hiện đại của i386 System V ABI (được sử dụng trên Linux) yêu cầu căn chỉnh 16 byte %esptrước a call, như Hệ thống V ABI x86-64 luôn luôn được yêu cầu. Callees được phép giả định rằng và sử dụng tải / lưu trữ 16 byte SSE có lỗi khi không được chỉ định. Nhưng trong lịch sử, Linux chỉ yêu cầu căn chỉnh ngăn xếp 4 byte, do đó, phải mất thêm công sức để dự trữ không gian được căn chỉnh tự nhiên ngay cả đối với 8 byte doublehoặc thứ gì đó.

Một số hệ thống 32 bit hiện đại khác vẫn không yêu cầu căn chỉnh ngăn xếp hơn 4 byte.

x86-64 Quy ước gọi chức năng không gian người dùng System V:

x86-64 System V vượt qua args trong các thanh ghi, hiệu quả hơn so với quy ước stack stack của i386 System V. Nó tránh được độ trễ và các hướng dẫn bổ sung về lưu trữ args vào bộ nhớ (bộ đệm) và sau đó tải lại chúng trong callee. Điều này hoạt động tốt bởi vì có nhiều thanh ghi có sẵn hơn và tốt hơn cho các CPU hiệu suất cao hiện đại, nơi có độ trễ và vấn đề thực thi không theo thứ tự. (ABI i386 rất cũ).

Trong cơ chế mới này : Đầu tiên các tham số được chia thành các lớp. Lớp của mỗi tham số xác định cách thức mà nó được truyền cho hàm được gọi.

Để biết thông tin đầy đủ, hãy tham khảo: “Trình tự gọi chức năng 3.2” của Giao diện nhị phân ứng dụng System V Bổ sung bộ xử lý kiến ​​trúc AMD64 , phần đọc:

Khi các đối số được phân loại, các thanh ghi được gán (theo thứ tự từ trái sang phải) để truyền như sau:

Nếu lớp là NHỚ, truyền đối số trên ngăn xếp. Nếu lớp là INTEGER, thì thanh ghi có sẵn tiếp theo của chuỗi% rdi,% rsi,% rdx,% rcx,% r8 và% r9 được sử dụng

Vì vậy, %rdi, %rsi, %rdx, %rcx, %r8 and %r9các thanh ghi theo thứ tự được sử dụng để truyền tham số nguyên / con trỏ (tức là lớp INTEGER) cho bất kỳ hàm libc nào từ assembly. % rdi được sử dụng cho tham số INTEGER đầu tiên. % rsi cho thứ 2,% rdx cho thứ 3, v.v. Sau đó, callhướng dẫn nên được đưa ra. Ngăn xếp ( %rsp) phải được căn chỉnh 16B khi callthực thi.

Nếu có nhiều hơn 6 tham số INTEGER, tham số INTEGER thứ 7 và sau đó được truyền vào ngăn xếp. (Người gọi bật lên, giống như x86-32.)

8 đối số dấu phẩy động đầu tiên được truyền vào% xmm0-7, sau đó trên ngăn xếp. Không có thanh ghi vector bảo tồn cuộc gọi. (Một hàm có kết hợp các đối số FP và số nguyên có thể có hơn 8 đối số thanh ghi tổng.)

Các hàm biến thể ( nhưprintf ) luôn luôn cần %al= số lượng thanh ghi FP args.

Có các quy tắc khi nào cần đóng gói cấu trúc vào các thanh ghi ( rdx:raxkhi trả về) so với trong bộ nhớ. Xem ABI để biết chi tiết và kiểm tra đầu ra của trình biên dịch để đảm bảo mã của bạn đồng ý với các trình biên dịch về cách một cái gì đó sẽ được chuyển / trả lại.

Xem thêm: Sinh Viên Năm Cuối Tiếng Anh Là Gì, Sinh Viên Năm 2 Tiếng Anh Là Gì

Lưu ý rằng quy ước gọi hàm Windows x64 có nhiều khác biệt đáng kể so với x86-64 System V, giống như không gian bóng phải được người gọi dành riêng (thay vì vùng đỏ) và xmm6-xmm15 được bảo toàn cuộc gọi. Và các quy tắc rất khác nhau mà arg đi trong đăng ký nào.

Chuyên mục: Hỏi Đáp