2012-06-21 2 views
5

PowerPC 어셈블리를 처음 사용합니다. 저는 MPC8245 (예, 오래된 학교)에서 일하고 있습니다. 이것은 603e 패밀리 프로세서입니다.PowerPC 어셈블리로드 즉시

즉각적인 16 비트 값이 '부호없는'로드 직접 실행 명령어를 만드는 방법을 알고 싶습니다.

예 : 리튬 r3,0xFC10

의 gcc 크로스 컴파일러, 4.4.5, 나는 값이 일정한 서명이 아니므로이 명령을 허용하지 않습니다 사용하고 있습니다.

예, 2 초의 보수를 사용할 수는 있지만 코드 읽기 및 문서화가 더 어려워집니다. 장치 레지스터의 비트 필드를로드 할 때 명령의 정확한 비트 필드를 읽으면 훨씬 쉽게 읽을 수 있습니다.

+0

-1008 0xFC10과 같은 2의 보수 표현을가집니다.어쩌면 당신은 (0xfc10-0x10000)을 쓸 수 있습니까? –

+0

또는 수동으로 0xFFFFFC10으로 부호 확장 하시겠습니까? –

+0

@tc - 흥미 롭습니다. li 명령어는 16 비트 값만 허용하지만 li r3,0xFFFFFC10은 올바른 명령어입니다. – KeithSmith

답변

10

li은 실제로 addi 명령으로 해석되는 의사 연산 코드입니다. rA 필드는 리터럴 0 대신 r0으로 지정되는 경우, 0이면

addi rD, rA, SIMM는 제외 rD, 에 결과를 배치 SIMMrA 즉시 서명 추가합니다. li rD, SIMM은 실제로 addi rD, 0, SIMM입니다.

이 값은 0 - 0x7fff0xffff8000 - 0xffffffff에서 값을로드하는 데 유용하지만 다른 값은로드 할 수 없습니다.

즉시 비트 연산 opcode (ori 등)는 16 비트 직접 필드를 부호없는 값으로 해석합니다. 그러나 "은 0 문자 그대로를 의미합니다"동작이 addi이 아닙니다.

당신은 레지스터에 0xfc10의 상수를로드하는 두 개의 명령어를 사용해야합니다 : (당신이 임의의 32 비트 상수의 위쪽 절반을로드하는 것처럼, 또는 lis) li를 사용하여 0 레지스터를로드 한 후 또는 부호가없는 16 비트 값인 ori.

$ cat test.c 
unsigned int test(void) 
{ 
    return 0xfc10; 
} 
$ gcc -O2 -c test.c 
$ objdump -d test.o 

test.o:  file format elf32-powerpc 

Disassembly of section .text: 

00000000 <test>: 
    0: 38 60 00 00  li  r3,0 
    4: 60 63 fc 10  ori  r3,r3,64528 
    8: 4e 80 00 20  blr 
    c: 60 00 00 00  nop 
$ 

내가 는 GNU 어셈블러가 하나에서 같은 값을로드하기 위해 자동으로 두 개의 명령어를 생성 어떤 방법이 있다고 생각하지 않습니다

gcc이 상황에서 무엇을하는지 정확히 PowerPC 용으로 어셈블 할 때 소스 명령. 당신은 상수, 예를 들어,의 (서명) 높고 낮은 16 비트 반쪽을 추출하기 위해 @h@l 접미사를 사용할 수 있습니다 그러나 :

lis r3, [email protected]   /* => li r3, 0x1234  */ 
ori r3, r3, [email protected]  /* => ori r3, r3, 0x5678 */ 

당신은 임의의 상수로드에 대한 자신의 매크로를 작성하려면이 옵션을 사용할 수 있습니다 .. .

$ cat test2.s 
     .macro load_const rD, const 
     .if (\const >= -0x8000) && (\const <= 0x7fff) 
     li  \rD, \const 
     .else 
     lis  \rD, \[email protected] 
     ori  \rD, \rD, \[email protected] 
     .endif 
     .endm 

     load_const r3, 0 
     load_const r4, 1 
     load_const r5, -1 
     load_const r6, 0x7fff 
     load_const r7, 0x8000 
     load_const r8, -32767 
     load_const r9, -32768 
     load_const r10, -32769 
     load_const r11, 0xfc10 

$ as -mregnames -o test2.o test2.s 
$ objdump -d test2.o 

test2.o:  file format elf32-powerpc 

Disassembly of section .text: 

00000000 <.text>: 
    0: 38 60 00 00  li  r3,0 
    4: 38 80 00 01  li  r4,1 
    8: 38 a0 ff ff  li  r5,-1 
    c: 38 c0 7f ff  li  r6,32767 
    10: 3c e0 00 00  lis  r7,0 
    14: 60 e7 80 00  ori  r7,r7,32768 
    18: 39 00 80 01  li  r8,-32767 
    1c: 39 20 80 00  li  r9,-32768 
    20: 3d 40 ff ff  lis  r10,-1 
    24: 61 4a 7f ff  ori  r10,r10,32767 
    28: 3d 60 00 00  lis  r11,0 
    2c: 61 6b fc 10  ori  r11,r11,64528 
$ 
+0

매트 - 철저한 대답에 감사드립니다. 내가 사용하고있는 빌드 환경은'lwi' 매크로를 가지고 있습니다. 부호없는 값을'li'과 함께 사용할 때 gcc가보고 한 오류는 위에서 언급 한 것처럼 Error : 피연산자가 범위를 벗어남 (0x00008000은 0xffff8000과 0x00007fff 사이에 있지 않음)입니다. – KeithSmith

0

또한 운영자 ori를 사용하여 즉시 부호없는 16 비트를로드,하지만 전에 등록을 취소해야합니다 수 :

xor r3, r3, r3 
ori r3, r3, 0xFC10