2016-10-13 2 views
1

나는 다음과 같은 어셈블리를 컴파일하기 위해 노력하고있어에 대한 피연산자 크기 불일치 ...오류 :`movq '

movq $0x3534373536383235, 0x000000000055638f8 
movq $0x55638f8, %rdi 
retq 

라인은 이해가되지 않습니다 오류 Error: operand size mismatch for 'movq'

를 던졌습니다 왜냐하면 둘 다 8 바이트 숫자이기 때문입니다.

이 나는 ​​약간의 연구와 movabsq

movabsq $0x3534373536383235, 0x000000000055638f8 
movq $0x55638f8, %rdi 
retq 

...과 같이, 추천되었다 그러나 이것은 오류가 발생 않았다 Error: operand size mismatch for 'movabs'

내가 놓치고 무엇을? 당신은 (일반적으로 인정 하듯이,이다, 협박 비트)를 보조 정리 MOV 아래의 설명서에 보면

가 여기 내 맥

level3.s:1:27: error: invalid operand for instruction 
movq $0x3534373536383235, 0x000000000055638f8 
          ^~~~~~~~~~~~~~~~~~~ 
+0

가능한 [movq 및 64 비트 숫자] (http://stackoverflow.com/questions/19582654/movq-and-64-bit-numbers) – AnT

+0

[AnT 's link] (https://stackoverflow.com/)의 가능한 복제본 질문/19582654/movq-and-64-bit-numbers)는 질문이 혼란 스럽거나 깨져서 훌륭한 dup 대상이 아닙니다 :'movq $ 0xffffffffffffffff, -8 (% rbp)'는 부호 확장 32 비트 즉각적인, 그리고 다른 문제, 그 질문에 대한 내 의견을 참조하십시오. –

답변

4

에서 전체 오류, 당신은 더 mov r/m64, imm64이 없다는 것을 발견 할 것이다.

전체 64 비트 상수를 레지스터에로드하는 방법이 있습니다. 64 비트 메모리 위치에 부호 확장 32 비트 상수를로드하는 방법이 있지만 64 비트를 즉각 사용하는 단일 명령은 없습니다. 기억.

임시 레지스터를 사용하거나 두 개의 dword를 메모리에 별도로 직접 쓰는 등 두 단계로 수행해야합니다. 그것을 할 수

2

한 가지 방법은 다음과 같습니다

movabsq $0x3534373536383235, %rax 
movabsq %rax, 0x000000000055638f8 

다른 의견이 말했듯이, 당신이 할 수없는 명령이 없기 때문에 64 비트 메모리 주소로 즉시 64 비트를 이동할 수 없습니다 . opcode는 현재 15 바이트를 초과 할 수 없으며 두 개의 64 비트 값은 16 바이트이므로 opcode의 일부 여야하므로이 opcode가 누락되었습니다. 이 제한 사항은 접두어가 너무 큰 작은 opcode에도 적용됩니다. 절대 64 비트 메모리 주소로 이동하기 때문에 어셈블러가 좋아하는 movabs 또는 movabsq를 사용하는 것이 좋습니다.

+0

OP는 64 비트 주소와 64 비트 상수를 모두 지정했습니다. – XorMalice

+0

왜 opcode가 15 바이트를 초과 할 수 없는지 아십니까? – jeteon

+1

@ jeteon : 15 바이트로 제한된 전체 * 명령어 *입니다. 옵 코드는 최대 2 바이트 이상이거나 필수 접두사를 포함하는 경우 더 많습니다. 이 제한은 빠른 디코더를보다 쉽게 ​​설계 할 수있게합니다. 원본 8086은 한 번에 1 바이트 씩 디코딩되지만 나중에 CPU는 전체 명령을 한 번에 디코딩합니다. 고정 너비의 버퍼가 항상 전체 명령을 유지할 수 있는지 확인하는 것이 유용합니다. IDK가 왜 16 개가 아닌 15 개를 골 랐는지 4 비트 카운터는 16 개가 아닌 15 개를 보유 할 수 있습니다. –