2014-11-22 2 views
1

그래서 JIT x86 기계 코드를 생성하고 직접 실행하는 프로그램이 있는데 x86-64/AMD64/x64도 지원하고 싶습니다. 명백한 차이점은 다음과 같습니다x86과 x86-64 기계 코드의 차이점

  • 새로운 레지스터 (rax, r8 ...) 및 포인터 폭
  • 기본 C 호출 규칙 (레지스터 대 스택에 인수)
  • (포인터는 64 비트 REGS를 사용해야합니다) 일부 새로운 연상 기호는

뿐만 아니라 바이너리 명령어의 차이가하거나 적절한 경우와 C pushq 및 64 비트 레지스터를 사용하는 (대략) 충분해야합니다 (pushq는 64 비트를 밀어) 오드가 효과가 있을까요?

코드 예제 :

static inline void emit_call(uint32_t target) { 
    emit_byte(0xE8); 
    emit_dword(target - ((uint32_t)out + 4)); 
} 

이 아직도 내가 uintptr_t를 사용하는 경우, 내가 생각하는 대신 uint32_t의 작동하지만 rax가 낮은 32 비트 별칭에로드 다른 64 비트 레지스터로 즉시로드 것 :

static void emit_mov_x86reg_immediate(int x86reg, int imm) { 
    emit_byte(0xB8 | x86reg); 
    emit_dword(imm); 
} 

다른 점이 있습니까?

코드를보고 싶다면 here에 액세스 할 수 있습니다.

+0

꽤 많은 차이가 있습니다. 일부는 내 (폐쇄) 질문에 나열되어 있습니다 http://stackoverflow.com/questions/11897116/how-to-convert-linux-32-bit-gcc-inline-assembly-to-64bit-code. – nrz

+0

'push'는 여전히 오래된 명령어이고 새로운 니모닉이 없으며 새로운 AT & T 접미사 만 사용되거나 접미사가 필요없는 Intel 구문을 사용합니다 –

답변

3

이전의 32 비트 푸시와 새로운 64 비트 푸시의 차이점은 64 비트의 몇 가지 지침 중 하나입니다.

상대 분기 및 호출은 여전히 ​​32 비트 오프셋을 사용합니다.

일부 실제 차이점은 다음과 같습니다

  • 렉스 접두사, 분명히, 여분의 레지스터 (! 또한 sildil 기억 - 여전히 중요 할 수있는 비트 세트의 없음과 REX 접두사를)
  • 렉스 접두사를 다시 사용하면 incdec의 짧은 인코딩 (40+rd, 48+rd)이었습니다. 따라서 incdecFF /1 인코딩이어야합니다.arpl
  • leslds에 직접 64 비트 주소
  • 로그인 확장 64 비트에 32 비트를 (movsxd) 주 연산 코드와
  • 64 비트 즉시 부하 및 mov를 해결
  • rip -relative VEX 재사용, 존재하지 않는 접두어 (32 비트 모드에서는 leslds만이 잘못된 피연산자로 된 VEX 접두사이므로 VEX 접두사의 인코딩이 약간 이상합니다.)
  • 아무도 사용하지 않는 몇 가지 오래된 지침 r은 제거 된 64 비트 모드에서 쓸모가 (소수점 수학, bound, into, pushad, pop es 친구) 80 /?
  • 82 /? 별칭 (
  • lahfsahf이 오래된의 x64 프로세서에 존재하지 않는 더 이상 유효하지 않습니다 어쨌든 그들을 사용하지 않을 것입니다.)
+0

REX 접두어는'cmpsq','lodsq','movsq', scasq'와'stosq'입니다. – nrz

관련 문제