2017-11-30 18 views
2

인라인 어셈블리에서 inb 명령어를 사용하는 일부 C 코드가 있습니다. 나는 inb가 8 비트 크기의 피연산자를 사용한다고 들었다. AL과 DL은 8 비트이기 때문에 왜 작동하지 않습니까?in-gcc 인라인 어셈블리의 피연산자 유형이 일치하지 않습니다.

__asm__ __volatile__("inb %al, %dl"); 

"피연산자 유형이 일치하지 않습니다"라고 표시됩니다. 중요한 경우 ".code16gcc"가 맨 위에 있습니다. 모든 도움을 주시면 감사하겠습니다.

+0

는 매개 변수 주위에 변경 될 필요가있다. 마찬가지로 [포트 레지스터] (http://www.felixcloutier.com/x86/IN.html)는 _DX_ _DL이 아니어야합니다. 마찬가지로 'AL'과 같은 레지스터를 변경하면 _GCC_에게 당신이 _EAX_을 (clobbered)했다고 말하십시오. 또한 어딘가에 적절히 옮기기 위해서는 몇 가지 제약 조건이 있어야합니다. 인라인 어셈블리는 매우 어렵고, 코드 프로젝트 튜토리얼은 그 중 하나를 이해하지 못하기 때문에 고통의 길을 걷게했다. –

+4

이와 같은 기능을 수행하는 올바른 방법은 다음과 같습니다. 'uint8_t inb (uint16_t port) { uint8_t ret; asm volatile ("inb % 1, % 0": "= a"(ret) : "dN"(포트)); return ret; }'. 보통 정적 인라인과 같은 기능을 표시하고 헤더 파일에 넣습니다. –

답변

1

두 가지 : AT 스타일T 스타일 어셈블리에서 대상 피연산자는 마지막이며 포트 번호는 데이터가 8 비트 인 경우에도 16 비트입니다. 그래서 : AT & T 구문이 두 번째로 첫 번째 피연산자과 이명 령으로 SRC 것처럼

inb %dx, %al 
+1

이렇게하면 어셈블 할 수 있지만 [@ MichaelPetch의 코드] (https://stackoverflow.com/questions/47579639/operand-type-mismatch-for-in-gcc-inline-assembly/47579797#comment82116781_47579639) 만 사용하면됩니다. 실제로 GNU C 인라인 asm *으로 사용할 수 있습니다. –