2017-09-10 5 views
0

인라인 어셈블리 코드를 작성하여 실시간 시계를 읽습니다. 'dl'로 읽을 레지스터 번호 (4)를로드하고이를 포트 0x70에로드합니다. 나는이 레지스터 값 (4)을 알로 읽으려고한다. 자세한 내용은 - RTCGNU 어셈블러 구문

asm(
"mov $4, %%dl;" 
"out 0x70, %%dl;" 
"in %%al, 0x71;" 
: 
: 
:"%al","%dl" 
); 

이 코드가 들어있는 C 파일을 컴파일에 오류 메시지가 아래 얻고있다.

Assembler messages:

Error: operand size mismatch for 'out'

Error: operand size mismatch for `in'

어셈블러 버전 : GNU 어셈블러 버전 2.26.1 (x86_64에-리눅스 GNU) (우분투 GNU Binutils의) BFD 버전을 사용 2.26.1

누군가가 문제를 지적시겠습니까?

+3

오류 메시지는 상수 앞에'$'이 없기 때문에 발생합니다. 즉, asm에 값을 출력하려면 첫 번째 콜론 뒤에 출력 매개 변수가 있어야합니다. 우분투를 실행하는 동안'in' 또는'out'을 사용할 수 있다면 놀랄 것입니다. 그리고 RTC를 읽기 전에'cli'한다고 생각하지 않습니까? 16 비트 코드를 작성하는 경우 64 비트 컴파일러를 사용하는 것이 효과가 있을지 잘 모르겠습니다. 그리고 부팅 할 때 RTC를 읽으 려한다면 [this] (https://stackoverflow.com/q/46074535/2189500)는 어떨까요? –

+2

AT & T 구문에는 일반적으로 오른쪽에 대상이 있습니다. 나는 IN과 OUT 명령에도이를 기대합니다. 'IN 0x71, %% al'? –

+0

@DavidWohlferd'iopl()'이나'ioperm()'시스템 호출을 사용하여'in'과'out'을 사용할 수 있습니다. – fuz

답변

4

많은 문제가 있습니다. 먼저 inout은 모두 A 레지스터 (al, ax, eax, rax)에서만 작동 할 수 있습니다. 둘째, 피연산자 순서가 잘못되어 세 번째로, 즉각적인 표현은 $이며 AT & T 구문이 접두어로 사용되어야합니다. 일반 조립, 귀하의 코드는 다음과 같아야합니다

mov $4,%al 
out %al,$0x70 
in $0x71,%al 

그래서 수정 된 어셈블리 나는 그 소리는이 코드를 조립하기 위해 명시 적으로 크기 접미사를 추가 한

asm(
"movb $4, %%al;" 
"outb %%al, $0x70;" 
"inb $0x71, %%al;" 
: 
: 
:"%al" 
); 

참고가 될 것입니다.

unsigned char result; 
volatile asm("outb %1,$0x70; inb $0x71, %0" : "=a"(result) : "a"((char)4)); 

이렇게하면 gcc가 약간 더 나은 코드를 생성 할 수 있습니다. 예를 들어, gcc는이 코드를 인라인 할 수 있습니다.

outb() 매크로를 사용하여 <sys/io.h>에서 인라인 어셈블리를 완전히 피할 수도 있습니다. 이것은 일반적으로 매우 좋은 일입니다.

+0

자세한 답변을 해주셔서 감사합니다. 그런 구문 오류를 피할 수 있도록 인라인 어셈블리의 AT & T 구문에 대한 포괄적 인 가이드를 알려주십시오. – SilentMonk

+0

@SilentMonk GNU 어셈블러 매뉴얼을 읽으십시오. – fuz

+0

또한 dl을 소스로 사용하는 명령이 없다는 것을 나타내는 좋은 명령어 세트 참조를 얻어야합니다. Intel 설명서 (https://software.intel.com/en-us/articles/intel-sdm)를 사용합니다. – prl