2012-02-19 25 views
48

Tôi muốn viết một chương trình cấp thấp nhỏ. Đối với một số phần của nó, tôi sẽ cần phải sử dụng ngôn ngữ lắp ráp, nhưng phần còn lại của mã sẽ được viết trên C/C++. Vì vậy, nếu tôi sẽ sử dụng GCC để trộn C/C++ với mã assembly, tôi có cần sử dụng cú pháp AT & T hoặc có thể Tôi sử dụng cú pháp của Intel không? Hoặc làm thế nào để bạn kết hợp C/C++ và asm (intel syntax) theo một cách khác?Tôi có thể sử dụng cú pháp x86 của Intel với GCC không?

Tôi nhận ra rằng có lẽ tôi không có sự lựa chọn và phải sử dụng AT & cú pháp T, nhưng tôi muốn chắc chắn ..

Và nếu có hóa ra là không có lựa chọn, nơi tôi có thể tìm thấy đầy đủ/tài liệu chính thức về cú pháp AT & T?

Cảm ơn!

+0

Nếu bạn viết một số chức năng toàn bộ trong asm, chúng có thể nằm trong tệp được biên dịch riêng. Nếu bạn không quan tâm đến sự phụ thuộc xây dựng trên YASM hoặc NASM, thì bạn sẽ dễ dàng sử dụng bất kỳ cú pháp nào bạn thích. (Nhưng sau đó asm của bạn phải đối phó với các ABIs khác nhau cho Windows và Linux, có thể với các macro lắp ráp.) [Hướng dẫn lắp ráp GNU trực tuyến] (https://sourceware.org/binutils/docs/as/), và thường được cài đặt với gcc/binutils. ('thông tin dưới dạng'). –

+0

Hãy cẩn thận với cú pháp của Intel vì bộ điều hợp tích hợp của Clang trên đó. Xem thêm [LLVM Issue 24232: Các toán hạng lắp ráp nội tuyến không hoạt động với .intel_syntax] (http://llvm.org/bugs/show_bug.cgi?id=24232). Báo cáo lỗi cho thấy Clang gặp rắc rối với một từ chối đơn giản. – jww

Trả lời

61

Nếu bạn đang sử dụng file lắp ráp riêng biệt, khí đốt có một chỉ thị để hỗ trợ Intel cú pháp:

.intel_syntax noprefix 

trong đó sử dụng cú pháp của Intel và không cần tiền tố% trước tên đăng ký.


Nếu bạn đang sử dụng lắp ráp nội tuyến, bạn có thể biên dịch với -masm=intel

Sử dụng .intel_syntax noprefix vào đầu asm nội tuyến, và chuyển đổi qua lại với .att_syntax thể làm việc, nhưng sẽ phá vỡ nếu bạn sử dụng bất kỳ m ràng buộc. Tham chiếu bộ nhớ sẽ vẫn được tạo trong cú pháp AT & T.

+1

Cảm ơn bạn, ninjalj !!!!!! – Hlib

+12

Đừng quên trả lại tiêu chuẩn AT & T vào cuối phần lắp ráp của bạn. '.att_syntax noprefix' thực hiện điều này. Khác, bộ lắp ráp sẽ cố gắng giải thích các trình biên dịch tạo ra mã lắp ráp, đó là trong định dạng AT & T, như định dạng Intel. – ugoren

+7

@ugoren: '-masm = intel' làm cho trình biên dịch tạo ra cú pháp Intel.Bạn thực sự cần nó để lắp ráp nội tuyến, nếu không '' m ''ràng buộc bộ nhớ sẽ không hoạt động. – ninjalj

4

Bạn có thể sử dụng lắp ráp nội tuyến với -masm = intel như ninjalj đã viết, nhưng nó có thể gây ra lỗi khi bạn đưa tiêu đề C/C++ sử dụng lắp ráp nội tuyến. Đây là mã để tái tạo các lỗi trên Cygwin.

sample.cpp: 
#include <cstdint> 
#include <iostream> 
#include <boost/thread/future.hpp> 

int main(int argc, char* argv[]) { 
    using Value = uint32_t; 
    Value value = 0; 
    asm volatile (
     "mov %0, 1\n\t" // Intel syntax 
//  "movl $1, %0\n\t" // AT&T syntax 
     :"=r"(value)::); 

    auto expr = [](void) -> Value { return 20; }; 
    boost::unique_future<Value> func { boost::async(boost::launch::async, expr) }; 
    std::cout << (value + func.get()); 
    return 0; 
} 

Khi tôi xây dựng mã này, tôi nhận được thông báo lỗi bên dưới.

g++ -E -std=c++11 -Wall -o sample.s sample.cpp 
g++ -std=c++11 -Wall -masm=intel -o sample sample.cpp -lboost_system -lboost_thread 
/tmp/ccuw1Qz5.s: Assembler messages: 
/tmp/ccuw1Qz5.s:1022: Error: operand size mismatch for `xadd' 
/tmp/ccuw1Qz5.s:1049: Error: no such instruction: `incl DWORD PTR [rax]' 
/tmp/ccuw1Qz5.s:1075: Error: no such instruction: `movl DWORD PTR [rcx],%eax' 
/tmp/ccuw1Qz5.s:1079: Error: no such instruction: `movl %eax,edx' 
/tmp/ccuw1Qz5.s:1080: Error: no such instruction: `incl edx' 
/tmp/ccuw1Qz5.s:1082: Error: no such instruction: `cmpxchgl edx,DWORD PTR [rcx]' 

Để tránh những lỗi này, cần phải tách cụm từ nội tuyến (phần trên của mã) từ mã C/C++ yêu cầu tăng :: tương lai và tương tự (nửa dưới). Tùy chọn -masm = intel được sử dụng để biên dịch các tệp .cpp chứa tập hợp nội tuyến cú pháp của Intel, không phải tệp .cpp khác.

sample.hpp: 
#include <cstdint> 
using Value = uint32_t; 
extern Value GetValue(void); 

sample1.cpp: compile with -masm=intel 
#include <iostream> 
#include "sample.hpp" 
int main(int argc, char* argv[]) { 
    Value value = 0; 
    asm volatile (
     "mov %0, 1\n\t" // Intel syntax 
     :"=r"(value)::); 
    std::cout << (value + GetValue()); 
    return 0; 
} 

sample2.cpp: compile without -masm=intel 
#include <boost/thread/future.hpp> 
#include "sample.hpp" 
Value GetValue(void) { 
    auto expr = [](void) -> Value { return 20; }; 
    boost::unique_future<Value> func { boost::async(boost::launch::async, expr) }; 
    return func.get(); 
} 
Các vấn đề liên quan