2010-11-18 3 views
1

저는 MIPS를 사용한다고 생각하는 pcsim 프로그램을 사용하고 있습니다. 나는 어셈블리 언어에 익숙하지 않기 때문에 긍정적이지 않다. 두 개의 32 비트 숫자에 add와 shift 만 사용하여 곱하고 두 개의 레지스터에 제품을 저장해야합니다. 결과가 32 비트로 저장 될 수 있다면 두 개의 숫자가 성공적으로 곱해질 곳을 찾았습니다. 문제는 그 수가 더 큰 경우 제품의 오른쪽 절반을 왼쪽 절반과 결합하는 방법을 알 수 없다는 것입니다. 왼쪽 절반 레지스터는 2^32에서 시작하는 값을 끝까지 유지해야합니다. 이것이 명확하지 않으면 더 설명하려고 할 수 있습니다. 내가 이것을 달성하기 위해 간과하는 쉬운 방법이 있습니까? 어떤 도움을 주셔서 감사합니다.어떻게 두 개의 32 비트 레지스터를 64 비트 응답으로 통합 할 수 있습니까?

답변

0

두 개의 반쪽을 하나의 32 비트 레지스터로 "결합"할 방법이 없습니다. 두 개의 절반을 메모리에 하나의 64 비트 값으로 결합하려면 컴퓨터의 엔디안에 따라 서로 반쪽을 저장해야합니다. SPIM을 사용 중이라면 호스트 컴퓨터와 동일한 enianness 엉덩이를 사용하는 것 같습니다.

x86? 스몰 엔디안. 하반부를 먼저 보관하십시오. PPC? 빅 엔디 언. 상반부를 먼저 보관하십시오.

1

정확하게 이해했다면 실제로 64 비트 산술 연산을해야 할 시점에 처하게 될 것입니다. 맞습니까?

일반적인 shift-and-add 바이너리 long 곱셈을 수행하는 경우 32 비트 연산에서 64 비트 이동 및 더하기 프리미티브를 생성 한 다음 동일한 방법을 사용할 수 있습니다.

다음은 C 조각의 예입니다 (실제로 사용하는 경우 MIPS로 변환하는 것이 간단해야 함). 난 당신이 서명되지 않은 32 비트 숫자로 작업하고 있다고 가정하고 부호없는 64 비트 결과를 원한다.

tmp = lo >> 31; /* top bit of lo to bottom bit of tmp, rest of tmp is 0 */ 
lo <<= 1; 
hi <<= 1; 
hi |= tmp; 

으로 논리 시프트를 잘 1 비트 :

으로 논리 시프트는 1 비트 왼쪽

tmp = hi << 31; /* bottom bit of hi to top bit of tmp, rest of tmp is 0 */ 
hi >>= 1; 
lo >>= 1; 
lo |= tmp; 

(사실 바꿀 수 1n(32 - n)31가 다른 번호로 이동하기 위해 비트 수)

64 비트 추가 :

result_lo = a_lo + b_lo; 
result_hi = a_hi + b_hi; 
if (result_lo < a_lo) 
    result_hi++; 

(이에 대한 자세한 내용은 MIPS와 관련하여 here 참조).


대체 방법은 각 32 비트 입력을 16 비트 "숫자"쌍으로 처리하는 것입니다. 두 개의 16 비트 숫자를 곱하면 최대 32 비트 결과가됩니다. 기본 아이디어는 다음과 같습니다.

0x12345678 * 0x23456789 =  0x5678 * 0x6789 
          + ((0x1234 * 0x6789) << 16) 
          + ((0x5678 * 0x2345) << 16) 
          + ((0x1234 * 0x2345) << 32) 

(여전히 일부 64 비트 추가가 필요합니다.)