2014-10-02 4 views
1

DR (디버그 레지스터) ID 번호를 받고 해당 DR 레지스터의 값을 반환하는 함수를 만들고 싶습니다. (DR0의 예) 같은견적 정의 내에서 변수 사용

뭔가 :

uint64_t readdr(uint8_t id) 
{ 
    uint64_t result; 
    asm volatile("movq %%dr0, %%rax\n" : "=a" (result)); 
    return result; 
} 

이 예는 단지 DR0 레지스터를 읽고 결과를 반환합니다. 나는이 기능은 DR의이 그래서 같은 필요한 모든 작동하려면 :

#define read_dr(x, result) "movq %%dr(x), %%rax\n" : "=a" (result)" 

을 한 후 나는 같은 것을 할 수 있습니다 :

asm volatile(read_dr(id, result)) 

은 그래서 모든 작동을 주어진 DR ID.

나는 그것이 작동하지 않는다는 것을 안다. 그러나 나는 그것이 내가 성취하려는 것을 분명히 해줄 것이라고 희망한다.

제안 사항?

+1

문자열 화 및 연결 연산자를 확인하십시오. 참조 https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html (가능한 것은 확실하지 않지만 그 경우 가능). –

+0

'id'가 정수 리터럴이 아니라 변수이기 때문에 define이 도움이되지 않습니다. 따라서 어셈블리 명령어에 포함시킬 수 없습니다. – interjay

+0

어셈블리에서 이러한 함수를 작성할 수 있습니까? –

답변

0

대답은 id가 컴파일 타임에 알려 졌는지 여부에 달려 있습니다. 예 :

#include <stdio.h> 

#define read_dr(id, result) \ 
    __asm__ (\ 
     "movq %%dr%c1, %0" \ 
     : "=r" (result) \ 
     : "i" (id) \ 
     : "cc") 

int main(int argc, char *argv[]) 
{ 
    long long a; 
    read_dr(1, a); 
    printf("%lld\n", a); 
} 

언제든지 컴파일러에서 ID를 상수로 확인할 수없는 경우 컴파일 오류가 발생합니다 (불가능한 제약 조건).

디버그 레지스터를 읽는 것은 권한이있는 명령입니다. 또한, 이것은 64 비트 코드입니다 (32 비트와 64 비트 모두 약간 더 멋진 버전이 가능합니다). 마침내 이것은 매크로로 작동 할 수 있지만 실제 기능 (forceinline은 제외)으로 작동하는지 의심 스럽습니다.