2016-12-07 1 views
0

다른 조립 질문입니다!8 비트 값을 포함하는 두 배열의 16 비트 내적을 어떻게 계산합니까?

Arduino를 사용하여 두 개의 배열의 내적을 계산하고 16 비트 정수로 반환하는 컴퓨터 과학 수업을위한 Atmel AVR 어셈블리에 함수를 작성해야합니다. 배열의 길이는 같고 각 배열은 8 비트 값 집합을 포함합니다. 함수는 두 개의 바이트 배열과 배열의 길이를 나타내는 바이트를 인수로 사용합니다. 나는 분기 명령 등을 사용할 수있다. ,

.global dot 
dot: 
    mov r18,r22 
    mov r19,r23 
    movw r26,r18 
    mov r30,r24 
    mov r31,r25 
    ldi r18,lo8(0) 
    ldi r19,hi8(0) 
    jmp exit_if 
    compute: 
    ld r25,Z+ 
    ld r22,X+ 
    muls r22,r25 
    movw r22,r0 
    clr r1 
    add r18,r22 
    adc r19,r23 
    exit_if: 
    mov r25,r30 
    sub r25,r24 
    cp r25,r20 
    brlt compute 
    movw r24,r18 
    ret 

내가 배열은 [] = {7 바이트 내가 알고있는 괴물의 조금 ... 어떤 이유

있을 때 : 여기

는 내가 지금까지 무엇을 가지고 20, 19, 11, 4} 바이트 b [] = {132, 51, 0, 84, 30}, 길이 인수가 5 인 경우 (분명히), 2988을 반환하지 않습니다. 누가 잘못되었는지 알 수 있습니까? 어떤 도움도 진심으로 감사 할 것입니다!

+3

코드에 약간의 주석을 달 수 있습니다. 우리가 명령어 세트와 ABI를 마음에두고 있다고 가정 할지라도, 이것은 서브 루틴의 예상되는 인수가 무엇인지 보여주지 않습니다. –

+0

왜 C 컴파일러를 사용하지 않습니까? AVR은 좋은 컴파일러 타겟이되도록 설계되었으므로 args를 취하여 결과를 반환하는 함수를 작성하고 gcc의 출력을 살펴보십시오. –

+1

'b [0] = 132'는 어셈블리와 일치하지 않습니다. 곱셈이 서명되었으므로 대신 -124가됩니다. –

답변

0

나는 모든 사람을 알아 냈습니다. 라인

muls r22, r25 

를 들어

내가 했어야은

mul r22, r25 

그래서 그것은 단지 하나의 작은 편지였다. 죄송합니다!

1

코드를 다소 높은 추상화 수준으로 변환하려고 시도했습니다.

.global dot 
dot: 
    mov r18,r22 
    mov r19,r23 
/* r18r19 = r22r23; */ 
    movw r26,r18 
/* X = r26r27 = r18r19; */ 
    mov r30,r24 
    mov r31,r25 
/* Z = r30r31 = r24r25; */ 
    ldi r18,lo8(0) 
    ldi r19,hi8(0) 
/* r18r19 = 0; */ 
/* jmp - innerlabel - testlabel pattern: while() loop */ 
    jmp exit_if 
    compute: 
    ld r25,Z+   // r25 = *(Z++) 
    ld r22,X+   // r22 = *(X++) 
    muls r22,r25  // multiplies vector elements, result in r0:r1 
    movw r22,r0  // r22r23 = a[i]*b[i], signed 
    clr r1   // r1=0 
    add r18,r22 
    adc r19,r23  // r18r19 += r22r23 
    exit_if: 
    mov r25,r30  // r25 = r30; 
    sub r25,r24  // r25 -= r24; 8-bit count of how many bytes have been read 
    cp r25,r20  // compare to r20 
    brlt compute // if r25<r20 loop 
    movw r24,r18 // r24r25 = r18r19 
    ret 

입력시 발견 된 레지스터 의미 : r20은 벡터 길이입니다. r24r25는 하나의 벡터 위치입니다. r22r23은 다른 벡터 위치입니다. 루프에서 합계를 추적하는 데 사용되는 설명 할 수없는 이유 인 r18r19의 경우 포인터 중 하나의 복사본을 일시적으로 보유합니다. 결과는 결국 r24 : r25에 배치됩니다.

이것은 합리적으로 작업을 수행 할 수 있습니다. 그래서 다음 질문은 정말로 ABI와 주장이 실제로 무엇인지입니다.

+0

예. 제 코드에 주석을 달아 주셔서 감사합니다. 이전에 직접 해보지 않아서 죄송합니다. 나는 원래의 질문을 편집하여 그 불일치가 어떤 논점을 추가 하는지를 추가했다. – stealthbomber10

관련 문제