Điều đầu tiên đó là lẽ vấp ngã bạn lên là danh sách được hỗ trợ trình biên dịch D của opcodes không bao gồm outb
, theo quy định của chức năng C mà bạn cung cấp. Sau khi đào một số, tôi đã phát hiện ra rằng outb
là một tên cụ thể hơn cho opcode chung out
. outb
cho biết đối số đầu tiên cho opcode sẽ được chứa trong thanh ghi byte (trái ngược với outw
và outl
, cho biết kích thước đối số đầu tiên, tương ứng, từ và từ kép), tuy nhiên trình biên dịch D sử dụng mã opcode out
cho tất cả các hoạt động, và xác định opcode cụ thể để viết dựa trên kích thước của đối số bạn chỉ định.
Bằng cách đó, điều tiếp theo cần làm là chuyển cú pháp GCC thành cú pháp D. Theo GCC-Inline-hội-HOWTO, mã mà bạn cung cấp sử dụng cú pháp lắp ráp mở rộng:
asm (assembler template
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
Nhìn vào mẫu của bạn, chức năng xác định một hướng dẫn lắp ráp (outb
) với hai đối số, đầu tiên là một byte (%b0
) và thứ hai là một từ hoặc một số nguyên ngắn (%w0
).
Bit khó hiểu về danh sách đối số đầu vào là chuỗi tiền tố mỗi thông số hàm của bạn. Những điều này, theo HOWTO, được gọi là những ràng buộc. Về cơ bản chúng là các quy tắc mà GCC phải tuân thủ trong việc sử dụng các tham số như các đối số cho các hướng dẫn lắp ráp được cung cấp.Ràng buộc "a"
được áp dụng cho thông số value
cho biết rằng nội dung của biến phải được đặt trong đăng ký eax
, ax
hoặc al
tùy thuộc vào kích thước của biến. Ràng buộc trên biến số port
, "Nd"
, cho biết giá trị đầu tiên nằm trong khoảng 0-255 và thứ hai, giá trị phải được đặt trong thanh ghi edx
, dx
hoặc một lần nữa, dựa trên kích thước của biến.
Trình biên dịch D không cung cấp nhiều trợ giúp với các biến trong các khối lắp ráp như GCC thực hiện; trong trình biên dịch nội tuyến của D, bạn sẽ cần phải di chuyển cụ thể các giá trị của các tham số vào các thanh ghi thích hợp. Đối với outb
, các thanh ghi này là dx
và al
. Sau cú pháp lắp ráp nội tuyến D's, bạn có thể di chuyển các biến và gọi out
opcode như sau:
asm
{
MOV AL, value;
MOV DX, port;
OUT DX, AL;
}
Lưu ý rằng, bởi vì GCC sử dụng AT & T cú pháp lắp ráp, và D sử dụng cú pháp lắp ráp Intel, thứ tự của các đối số được cung cấp cho OUT
bị đảo ngược.