Trong lịch sử, các trình biên dịch C tạo ra mã assembly, sau đó sẽ được một bộ lắp ráp dịch sang mã máy. Việc lắp ráp nội tuyến phát sinh như một tính năng đơn giản - trong mã lắp ráp trung gian, tại thời điểm đó, tiêm một số mã do người dùng chọn. Một số trình biên dịch trực tiếp tạo ra mã máy, trong trường hợp này chúng chứa một bộ lắp ráp hoặc gọi một bộ ghép bên ngoài để tạo mã máy cho các đoạn mã lắp ráp nội tuyến.
Cách sử dụng phổ biến nhất cho mã lắp ráp là sử dụng các hướng dẫn xử lý chuyên biệt mà trình biên dịch không thể tạo. Ví dụ, vô hiệu hóa các ngắt cho một phần quan trọng, kiểm soát các tính năng của bộ xử lý (cache, MMU, MPU, quản lý điện năng, truy vấn CPU,…), truy cập các bộ xử lý và thiết bị ngoại vi phần cứng (ví dụ: inb
/outb
hướng dẫn trên x86), v.v. hiếm khi tìm thấy asm("movl %ecx %eax")
, bởi vì điều đó ảnh hưởng đến các thanh ghi đa năng mà mã C xung quanh nó cũng đang sử dụng, nhưng một cái gì đó như asm("mcr p15, 0, 0, c7, c10, 5")
đã sử dụng nó (hàng rào bộ nhớ dữ liệu trên ARM). OSDev wiki có một số ví dụ với đoạn mã.
Mã lắp ráp cũng hữu ích để triển khai các tính năng phá vỡ mô hình điều khiển luồng của C. Một ví dụ phổ biến là bối cảnh chuyển đổi giữa các chủ đề (cho dù hợp tác xã hoặc preemptive, cho dù trong cùng một không gian địa chỉ hay không) đòi hỏi mã lắp ráp để lưu và khôi phục lại các giá trị đăng ký.
Mã lắp ráp cũng hữu ích để tối ưu hóa thủ công các bit mã nhỏ cho bộ nhớ hoặc tốc độ. Khi các trình biên dịch ngày càng trở nên thông minh hơn, điều này hiếm khi liên quan ở cấp ứng dụng hiện nay, nhưng nó vẫn có liên quan trong nhiều thế giới nhúng.
Có hai cách để kết hợp lắp ráp với C: với lắp ráp nội tuyến hoặc bằng cách nối các mô-đun lắp ráp với các mô-đun C. Liên kết được cho là gọn gàng hơn nhưng không phải lúc nào cũng áp dụng: đôi khi bạn cần một lệnh ở giữa chức năng (ví dụ để tiết kiệm đăng ký trên một chuyển ngữ cảnh, một cuộc gọi hàm sẽ ghi đè thanh ghi) hoặc bạn không muốn trả chi phí của một cuộc gọi hàm.
Hầu hết các trình biên dịch C đều hỗ trợ lắp ráp nội tuyến, nhưng cú pháp thay đổi. Nó thường được giới thiệu bởi từ khóa asm
, _asm
, __asm
hoặc __asm__
. Ngoài mã assembly, cấu trúc assembly nội tuyến có thể chứa mã bổ sung cho phép bạn truyền các giá trị giữa assembly và C (ví dụ, yêu cầu giá trị của biến cục bộ được sao chép vào thanh ghi trên mục nhập), hoặc khai báo mã lắp ráp ghi đè hoặc bảo tồn một số thanh ghi nhất định.
Để theo dõi "bạn thực sự cần biết mình đang làm gì". Lời cảnh cáo rằng các dòng chính xác của lắp ráp mà bạn có ý định nội tuyến, không phải luôn luôn được vinh danh chính xác bởi trình biên dịch. Tôi đã trải qua các trình biên dịch tạo ra những thay đổi tinh tế. Luôn luôn có một cái nhìn tốt về tháo gỡ sau khi biên dịch để đảm bảo nó làm chính xác những gì được dự định. – BabaBooey
Tôi tin rằng chúng được vinh danh chính xác nếu bạn cũng thêm công cụ chỉ định 'biến động ', ví dụ: '__asm__ volatile (" instrs ");' – slugonamission
Bạn cũng cần phải biết bộ xử lý nào (gia đình) mã của bạn sẽ chạy trên và, trong một số trường hợp, mô hình bộ nhớ nào. ANSI-C có thể được biên dịch cho hầu như mọi bộ xử lý và hệ điều hành nhưng hướng dẫn asm là * không * xách tay. –