0

즉시, 음수 돌아 내가 86 자신을 가르치려고 노력하고있어, 나는 필요에 걸쳐 실행했습니다 :이 기능 (printf("%" PRIdPTR "\n", scheme_entry())의 반환 값을 인쇄 할 때x86에서 즉시 64 비트 음수를 인코딩 할 수 있습니까?

.text 
.align 4,0x90 
.globl _scheme_entry 
_scheme_entry: 
movl $-42, %eax 
ret 

를, 내가 얻을 말도 안되는 번호 : 대신 64 비트의, 부정적인 00000000FFFFFFFF 32 비트 부정적이기 때문에

$ ./neg             
4294967254 

나는이 같은데요은 FFFFFFFFFFFFFFFF입니다

내가 상수 64 비트 값을 저장할 수있는 방법. 어셈블러 기능에서 직접 에? 두 가지 별도의 지침으로 인코딩해야합니까?

+0

잘못 인쇄하지 않으셨습니까? 'scheme_entry'는 32 비트 정수를 반환하는 것 같습니다 (그렇지 않다면'eax'에 넣는 이유는 무엇입니까?) – harold

+0

gcc는 함수 엔트리 포인트를 16 바이트로 정렬합니다. 덧붙여 패딩이 1 바이트 NOP (절대 실행되지 않기 때문에)가되도록하는 이유도 없습니다. '.p2align 4'를 사용하여'1 << 4'로 정렬하십시오. (아주 작은 함수의 경우 8 바이트 경계가 전체 함수를 포함하므로'.p2align 3'을 사용할 수 있습니다.) 최신 CPU는 오래된 CPU와 같이 코드 정렬에 민감하지 않지만 일반적으로 NOP 패딩은 실행되지 않습니다. –

+0

@PeterCordes 꽤 많이 그게 내 머리 위로있다. 나는 [컴파일러 작성 튜토리얼] (http://scheme2006.cs.uchicago.edu/11-ghuloum.pdf)을 따라 가며 의도적으로 우리를 아주 작은 C 입력에 대해 gcc 출력을 사용하여 컴파일러에서 무엇을 방출할지 결정하십시오. 위의 상용구는 기본적으로 축 어적으로 복사되었지만 나는 그것이 무엇을하는지 아직 알지 못했습니다! : x – ELLIOTTCABLE

답변

3

32 비트 명령어 용 32 비트 명령어 (예 : movl)는있는 그대로 사용되며 writing EAX zeros the upper 32 bits of RAX입니다. 당신은 말도 안되는 소리가 아닙니다. x86이 2의 보수 부호가있는 정수를 사용하기 때문에 정확히 예상 할 수있는 것은 2^32 - 42입니다.

64 비트 피연산자 크기의 명령어에 대한 32 비트 직선은 64 비트로 부호 확장됩니다.

mov $-42, %rax을 사용하면 양수 64 비트 값을 2^32보다 약간 작은 값으로 설정하는 대신 음수 64 비트 값을 반환 할 수 있습니다. 대상으로 %rax을 사용하면 64 비트 피연산자 크기 즉, movq을 의미합니다.

레지스터의 값을 보려면 디버거를 사용하십시오.

+0

이것은 훌륭한 정보입니다! 예, 저는 2의 보수를 알고있었습니다. 그러나'% rax' (그리고'mov'''''' movl''')는 내가 여기에서 놓치고있는 부분이었습니다. 나는 이것과 함께 달릴 것이다! 고맙습니다! – ELLIOTTCABLE

+2

@ELLIOTTCABLE 오히려 movl 대 movq. 접미어는 피연산자에서 명확한 경우 생략 할 수 있습니다. – fuz

관련 문제