AMD는 REX
접두어에 새로운 opcode를 추가하고 64 비트 x86 확장을 개발할 때 새로운 지침을 추가해야했습니다. 그들은 일부 연산 코드의 의미를 새로운 명령어로 변경했습니다.
지침 중 일부는 기존 지침의 단순한 형식이거나 그렇지 않으면 필요하지 않았습니다. PUSHA
이 희생자 중 하나였습니다. 그것은 왜 그들이 PUSHA
을 금지했는지 명확하지 않지만, 새로운 명령어 opcode와 겹치지 않는 것 같습니다. 아마도 그들은 완전히 중복되어 더 빠르지 않고 문제가되는 코드에서 자주 발생하지 않기 때문에 이후 사용을 위해 PUSHA
및 POPA
opcode가 예약되어있을 수 있습니다. eax
, ecx
, edx
, ebx
, esp
, ebp
, esi
, edi
:
PUSHA
순서
는 명령어 인코딩의 순서였다. 중복하여
esp
을 밀어 넣었습니다. 푸시 한 데이터를 찾으려면
esp
을 알아야합니다!
코드를 변환 할 때 PUSHA
코드가 좋지 않으면 새 레지스터 r8
을 통해 r15
을 푸시하도록 코드를 업데이트해야합니다.훨씬 더 큰 SSE 상태 인 xmm8
부터 xmm15
까지 저장하고 복원해야합니다. 당신이 그들을 clobber 것이라고 가정합니다.
인터럽트 처리기 코드가 단순히 C 코드로 전달되는 스텁 일 경우 모든 레지스터를 저장할 필요가 없습니다. C 컴파일러가 rbx
, rbp
, rsi
, rdi
및 r12
을 통해 r15
을 유지하는 코드를 생성한다고 가정 할 수 있습니다. rax
, rcx
, rdx
및 r8
부터 r11
까지만 저장하고 복원하면됩니다. - (주 리눅스 나 다른 시스템 V ABI 플랫폼에서 컴파일러는 rbx
, rbp
, r12
보존됩니다 r15
을, 당신은 rsi
및 사방 rdi
을 예상 할 수있다).
세그먼트 레지스터는 긴 모드에서 값을 유지하지 않습니다. 인터럽트 된 스레드가 32 비트 호환 모드에서 실행 중이면 세그먼트 레지스터를 보존해야합니다 (감사합니다 ughoavgfhw). 사실, 그들은 긴 모드에서 대부분의 세분화를 없애지 만, FS
은 여전히 운영 체제가 스레드 로컬 데이터의 기본 주소로 사용하도록 예약되어 있습니다. 레지스터 값 자체는 중요하지 않으므로 FS
및 GS
의 밑수는 MSR 0xC0000100
및 0xC0000101
을 통해 설정됩니다. FS
을 사용하지 않는다고 가정하면 걱정할 필요가 없습니다. C 코드로 액세스되는 모든 스레드 로컬 데이터는 임의 스레드의 TLS를 사용할 수 있습니다. C 런타임 라이브러리는 일부 기능에 TLS를 사용하기 때문에주의하십시오 (예 : strtok은 일반적으로 TLS를 사용합니다).
FS
또는 GS
(사용자 모드에서도) 값을로드하면 FSBASE
또는 GSBASE
MSR을 덮어 씁니다. 일부 운영 체제는 GS
을 "프로세서 로컬"저장소로 사용하기 때문에 (사용자가 각 CPU의 구조에 대한 포인터를 가질 수있는 방법이 필요합니다) 사용자 모드에서 GS
을로드하여 어쩔 수없이 어딘가에 보관해야합니다. 이 문제를 해결하기 위해 GSBASE
레지스터에 예약 된 2 개의 MSR이 있습니다 : 활성 1 개와 숨겨진 1 개. 커널 모드에서 커널의 GSBASE
은 보통 GSBASE
MSR에 있고 사용자 모드는 다른 (숨겨진) GSBASE
MSR에 있습니다. 커널 모드에서 사용자 모드 컨텍스트로 컨텍스트를 전환 할 때 및 사용자 모드 컨텍스트를 저장하고 커널 모드로 전환 할 때 컨텍스트 스위치 코드는 표시되고 숨겨진 GSBASE
MSR의 값을 바꿔주는 SWAPGS 명령을 실행해야합니다. 커널의 GSBASE
은 사용자 모드에서 다른 MSR에 안전하게 숨겨져 있기 때문에 사용자 모드 코드는 GS
에 값을로드하여 커널의 GSBASE
을 훼손 할 수 없습니다. CPU가 커널 모드로 다시 들어가면 컨텍스트 저장 코드는 SWAPGS
을 실행하고 커널의 GSBASE
을 복원합니다.
[wiki 기사] (http://en.wikipedia.org/wiki/X86-64)에서 x86-64는 x86과 하위 호환이 가능합니다. 명령을 제거해도 호환성이 깨지지 않습니까? –
@Ciro Santilli 六 四 事件 法輪 호환성 모드가 켜져 있어야하며, 그렇지 않으면 이전 버전과 호환되지 않습니다. –