2016-12-07 1 views
0

Другой вопрос сборки!Как вычислить 16-разрядное точечное произведение двух массивов, содержащих 8-битные значения?

Используя Arduino, я должен написать функцию в сборке Atmel AVR для моего класса информатики, которая вычисляет произведение точек двух массивов и возвращает его как 16-разрядное целое число. Массивы имеют одинаковую длину и каждый содержит набор 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 предназначен для хорошей цели компилятора, поэтому напишите функцию, которая принимает аргументы и возвращает результат, и посмотрите на вывод 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

Смежные вопросы