2009-09-06 23 views
5

Tôi đã giao dịch với Nasm trên môi trường Linux một thời gian và chức năng này hoạt động tốt ... nhưng giờ tôi đang chuyển sang môi trường cửa sổ và tôi muốn sử dụng Masm (với VS2008) dường như được điều này để làm việc ...Chuyển đổi vấn đề: __asm__ __volatile__

void outportb (unsigned short _port, unsigned short _data) 
{ 
    __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); 
} 

Khi tôi viết một cái gì đó như thế này ...

void outportb (unsigned short _port, unsigned short _data) 
{ 
    asm volatile ("outb %1, %0" : : "dN" (_port), "a" (_data)); 
} 

asm là không công nhận hơn và ném ổn định một lỗi nói rằng "chuỗi", tôi cũng đã cố gắng viết _asm dễ bay hơi nhưng tôi nhận được một lỗi nói "lỗi cú pháp lắp ráp nội tuyến trong 'opcode'; tìm thấy 'dữ liệu gõ ' '

Trả lời

8

Giả sử bạn đang nói về tập lệnh x86, sau đây là vài điều cần nhớ:

  1. hướng dẫn 'OUTB' đầu ra một byte, đó sẽ là tương đương với gõ 'char' hoặc' unsigned char "trong C/C++. Để xuất 16 bit (vì bạn đang sử dụng từ "unsigned short"), bạn cần sử dụng từ "outw"
  2. khi nói rằng, bạn nên dùng Intel (và yêu cầu bởi VS) để bạn sử dụng lệnh ghi nhớ " "và kích thước cổng được nhận ra từ kích thước toán hạng. Ví dụ "ra dx, rìu" sẽ tương đương cho "outw", trong khi "ra dx, al" là tương đương cho "OUTB"
  3. trên x86 là "out" hướng dẫn yêu cầu các cảng và giá trị xuất ra được đặt vào thanh ghi (e) dx và {eax/ax/al} tương ứng. Trong khi Nasm có thể làm điều đó cho bạn (tôi không có trình biên dịch tiện dụng, vì vậy tôi không thể xác nhận điều đó), trong VS bạn phải làm điều đó theo cách nó được thực hiện trên mức CPU.
  4. không có lý do gì để chỉ định từ khóa "dễ bay hơi" với __asm. Bất kỳ hướng dẫn lắp ráp nội tuyến gây VS biên dịch để vô hiệu hóa bộ nhớ đệm đọc (những gì từ khóa dễ bay hơi là cho)

Đây là mã (giả sử bạn đang viết vào cổng 16-bit):

void outportw(unsigned short port, unsigned short data) 
{ 
    __asm mov ax, data; 
    __asm mov dx, port; 
    __asm out dx, ax; 
} 

trong trường hợp bạn đang viết vào cổng 8 bit, mã phải giống như sau:

void outportb(unsigned short port, unsigned char data) 
{ 
    __asm mov al, data; 
    __asm mov dx, port; 
    __asm out dx, al; 
} 
+1

Ngoài ra: bạn có thể sử dụng __asm ​​{hướng dẫn tại đây} để có cú pháp rõ ràng hơn và có thể đáng nhắc đến, nội tuyến sẽ không làm việc trên x64, do đó, đối với kiến ​​trúc này sẽ phải viết mã asm e trong mã độc lập. –

+0

Ok bây giờ nó có ý nghĩa một chút, ít nhất là không nhận được lỗi .. vì vậy những gì là tương đương với inportb? Tôi biết bạn viết "in" thay vì "out" và có lẽ thay đổi rìu thành al phải không? Hay nó phức tạp hơn thế? – Fredrick

+0

Hãy thử nó, nó không nên làm tổn thương. Hãy nhớ rằng VS sử dụng thứ tự {operation} {destination}, {source}, vì vậy để đọc cổng, nó sẽ là: __asm ​​trong al, dx; và sau đó bạn cần lưu trữ kết quả trong biến của mình: __asm ​​dữ liệu mov, al; và trả lại từ hàm: trả về dữ liệu; – Rom

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