GCC에서 x86 어셈블리의 Intel 구문을 사용할 수 있습니까?
나는 작은 낮은 수준의 프로그램을 만들고 싶다.일부 부품은 어셈블리 언어를 사용해야 하지만 나머지 코드는 C/C++로 작성됩니다.
따라서 GCC를 사용하여 C/C++와 어셈블리 코드를 혼재시킬 경우 AT&T 구문을 사용해야 합니까?아니면 인텔 구문을 사용할 수 있습니까?또는 C/C++와 asm(인텔 구문)을 다른 방법으로 혼재시키는 방법은 무엇입니까?
어쩔 수 없이 AT&T 구문을 사용해야 한다는 것을 알고 있습니다만, 확실히 하고 싶습니다.
선택사항이 없는 경우 AT&T 구문에 대한 전체/공식 문서는 어디서 찾을 수 있습니까?
감사합니다!
별도의 어셈블리 파일을 사용하는 경우 gas는 Intel 구문을 지원하도록 지시합니다.
.intel_syntax noprefix # not recommended for inline asm
인텔 구문을 사용하여 레지스터 이름 앞에 % 프리픽스가 필요 없습니다.
(실행도 가능)as
와 함께-msyntax=intel -mnaked-reg
그것을 디폴트로 하다att
를 붙이기 싫을 경우.intel_syntax noprefix
를 참조해 주세요.)
인라인 asm: 컴파일 대상-masm=intel
인라인 어셈블리의 경우 C/C++ 소스를 사용하여 컴파일할 수 있습니다('인텔 구문을 영속적으로 사용하도록 gcc를 설정하는 방법' 참조).자세한 것은, 을 참조해 주세요).컴파일러의 자체 asm 출력(인라인 asm이 삽입됨)은 Intel 구문을 사용하고 오퍼랜드를 다음과 같은 Intel 구문을 사용하여 asm 템플릿 문자열로 대체합니다.[rdi + 8]
대신8(%rdi)
.
이는 GCC 자체 및 ICC에서 작동하지만 clang 14 이후에만 작동합니다.
(아직 출시되지 않았지만 패치는 현재 트렁크에 있습니다).
사용..intel_syntax noprefix
인라인 asm 시작 시 및 스위치백.att_syntax
동작할 수 있지만, 어느쪽인가를 사용하면 망가집니다.m
제약.메모리 레퍼런스는 AT&T 구문으로 계속 생성됩니다.GAS가 레지스터를 받아들이기 때문에 레지스터에 사용할 수 있습니다.%eax
intel-noprefix 모드에서도 레지스터 이름으로 사용됩니다.
사용..att_syntax
의 마지막에asm()
스테이트먼트는 또한 와의 컴파일도 깨집니다.-masm=intel
이 경우 템플릿은 GCC의 자체 asm 뒤에 (및 그 전에) Intel 구문입니다.(Clang에는 "문제"가 없습니다.템플릿 문자열이 실제로 GCC가 전송하는 텍스트파일의 일부가 되는 GCC와는 달리 각 asm 템플릿 문자열은 로컬입니다.as
조립할 수 있습니다.
연관된:
- GCC 매뉴얼: ASM 사투리 대체: GCC 매뉴얼:
asm
「」가 붙은 .{att | intel}
합니다.-masm=att
or or or openicle.-masm=intel
의 예를 참조해 주세요.lock cmpxchg
. - 일반적으로 인라인 어셈블리에 대한 자세한 내용은 https://stackoverflow.com/tags/inline-assembly/info를 참조하십시오.읽고 쓰는 레지스터와 메모리를 알 수 있도록 컴파일러에 asm을 정확하게 설명하는 것이 중요합니다.
- AT&T 구문: https://stackoverflow.com/tags/att/info
- 인텔 구문: https://stackoverflow.com/tags/intel-syntax/info
- x86 태그 Wiki에는 매뉴얼, 최적화 가이드 및 튜토리얼 링크가 있습니다.
ninjalj의 기술대로 -masm=intel과 함께 인라인 어셈블리를 사용할 수 있지만 인라인 어셈블리를 사용하여 C/C++ 헤더를 포함하면 오류가 발생할 수 있습니다.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;
}
이 코드를 작성했을 때, 아래와 같은 에러 메세지가 표시됩니다.
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]'
이러한 에러를 회피하려면 인라인어셈블리(코드의 상반부)를 C/C++ 코드로부터 분리해야 합니다.이 코드는 부스트:: future 등(하부)을 필요로 합니다.-masm=intel 옵션은 다른 .cpp 파일이 아닌 Intel 구문 인라인 어셈블리를 포함하는 .cpp 파일을 컴파일하기 위해 사용됩니다.
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();
}
언급URL : https://stackoverflow.com/questions/9347909/can-i-use-intel-syntax-of-x86-assembly-with-gcc
'source' 카테고리의 다른 글
char 배열을 문자열로 다시 변환하는 방법 (0) | 2022.07.23 |
---|---|
C의 값 주소 또는 포인터를 인쇄합니다. (0) | 2022.07.23 |
Java에서 메모리 누수를 작성하려면 어떻게 해야 하나요? (0) | 2022.07.23 |
포획은 루프 안쪽으로 할까요, 아니면 바깥쪽으로 할까요? (0) | 2022.07.23 |
Vue 3 - 대체 Vue.delete (0) | 2022.07.23 |