:
template <int N> static inline void GetInInterrupt (void)
{
__asm__ ("int %0\n" : "N"(N));
}
할 것입니다. 내가 사용하는 경우 해당 템플릿과 같은 :
0: cd 7b int $0x7b
2: cc int3
3: cd 17 int $0x17
5: cd 00 int $0x0
(심지어는 중단 영업 이익 인 int3
경우, 위해) 거의 최적 다음 오브젝트 코드를 생성
GetInInterrupt<123>();
GetInInterrupt<3>();
GetInInterrupt<23>();
GetInInterrupt<0>();
. 피연산자가 0..255
범위를 벗어나면 N
제약 조건 만 허용되므로 컴파일 타임 경고가 생성됩니다.
편집 : 보통 오래된 C 스타일 매크로는 물론, 잘 작동 :
#define GetInInterrupt(arg) __asm__("int %0\n" : : "N"((arg)) : "cc", "memory")
는 C++ 템플릿 함수와 같은 코드를 작성합니다. int
의 작동 방법으로 인해 컴파일러에게 ("cc", "memory"
제약 조건을 통해) 장벽 의미에 대해 알리고 인라인 어셈블리를 포함 할 때 지침을 다시 주문하지 않도록하십시오.
두 가지 제한은 분명히 인터럽트 번호가 컴파일 타임 상수 여야한다는 사실입니다. 당신이 그것을 원하지 않는다면, 예를 들어 switch()
문을 생성하십시오. 모든 2백55가지 경우를 포함하는 BOOST_PP_REPEAT()
의 도움으로 자기 수정 코드보다 더 나은 옵션입니다으로, 즉 같은 :
#include <boost/preprocessor/repetition/repeat.html>
#define GET_INTO_INT(a, INT, d) case INT: GetInInterrupt<INT>(); break;
void GetInInterrupt(int interruptNumber)
{
switch(interruptNumber) {
BOOST_PP_REPEAT(256, GET_INTO_INT, 0)
default:
runtime_error("interrupt Number %d out of range", interruptNumber);
}
}
당신이 __asm__
일반의 템플릿 함수 호출을 변경하면이 가 (일반 C에서 할 수 있습니다 물론) - 부스트 전처리 기 라이브러리가 이 아니기 때문에은 C++ 컴파일러에 의존합니다 ... 그리고 gcc 4.7.2이 다음 코드 작성
GetInInterrupt:
.LFB0:
cmpl $255, %edi
jbe .L262
movl %edi, %esi
xorl %eax, %eax
movl $.LC0, %edi
jmp runtime_error
.p2align 4,,10
.p2align 3
.L262:
movl %edi, %edi
jmp *.L259(,%rdi,8)
.section .rodata
.align 8
.align 4
.L259:
.quad .L3
.quad .L4
[ ... ]
.quad .L258
.text
.L257:
#APP
# 17 "tccc.c" 1
int $254
# 0 "" 2
#NO_APP
ret
[ ... accordingly for the other vectors ... ]
그래도 조심 위 ... 컴파일러를 할 경우 (그리고 4.8를 포함하여 최대 GCC)입니다 하지 즉 경우에도, 멀리 switch()
을 최적화 할만큼 지능static __inline__ ...
라고 말하면 더 간단한 구현처럼 인라인 대신 GetInInterrupt(3)
의 전체 점프 테이블 버전을 생성합니다.
실제로 무엇을하려고합니까? 그리고 "clobbered list"에''al "'(또는 eax)를 추가해야합니다. 아니면 컴파일러가 여러분의 계획을 망칠 eax로 조만간 뭔가를 할 것입니다. 0으로 나누기 오류를 호출 하시겠습니까? –
"al"을 clobbered 목록에 추가하는 것이 좋습니다. 감사합니다. "int"명령 다음에 "인터럽트"변수에 저장된 값으로 $ 0을 변경하려고합니다. – hrust
당신은 할 수 없습니다 - 코드는 읽기 전용입니다. 'mprotect' 또는'VirtualProtect'에 코드를 추가하는 것을 포함하여 훨씬 더 많은 코드를 작성해야합니다. 그러면 코드를 읽기 전용 대신 읽기 - 쓰기로 설정할 수 있습니다. 어떤 인터럽트를 호출할지 알지 못하는 이유는 무엇입니까? –