BG Development


  Reply to this topicStart new topicStart Poll

> Помощ за задача (ARM Assembly)
jfclol
Публикувано на: 25-05-2018, 20:00
Quote Post



Име:
Група: Потребител
Ранг: Новопостъпил

Мнения: 4
Регистриран на: 21.02.17



Да се напише подпрограма която да записва от адрес в регистър R0 масив от полудуми със знак, получавайки ги от съответните байтове на масив от байтове без знак с начален адрес и брой байтове съответно в регистри R0 и R1 чрез изваждане на 2^7 и умножение по 1.5

Ако някой може да помогне ще съм много благодарен ^^
PMEmail Poster
Top
AK-85
Публикувано на: 26-05-2018, 18:41
Quote Post



Име:
Група: Потребител
Ранг: Старо куче

Мнения: 748
Регистриран на: 06.07.06



Условието или е грешно, или е непълно. Или изходният масив не е в R0 (защото там е входният), или паметта трябва да се задели от подпрограмата, след което да се върне в R0. Ако е вторият случай, трябва да се укаже как да се задели паметта.

Иначе можеш да започнеш с тази тема. В това съобщение имаш код, който можеш да използваш като шаблон, а тук имаш описана проста алтернатива, при която започваш с код на C и получаваш решението, което търсиш.
PM
Top
AK-85
Публикувано на: 09-06-2018, 02:24
Quote Post



Име:
Група: Потребител
Ранг: Старо куче

Мнения: 748
Регистриран на: 06.07.06



Има още една подробност, която условието на задачата не уточнява - как да се закръгля резултатът, който е целочислен, потенциално отрицателен, но е резултат от умножение с дробно число. Иначе в тази задача няма редукция и всички итерации са напълно независими, съответно пак ме човъркаше да напиша векторно решение, пък и намерих приложение на halving инструкциите. За разнообразие кодът е в T32 (т.е. "Thumb"), изходният масив се заделя с malloc(), а закръглянето е към нулата като в C:
CODE
      .syntax unified
      .thumb
      .text
      .align      2
      # int16_t *transform(const uint8_t *a, size_t n)
      .global      transform
      .thumb_func
      .type      transform, %function
transform:
      mov      r3, #0
      cbz      r1, 1f

      push      {r4, r5, lr}
      mov      r4, r0
      mov      r5, r1
      lsl      r0, r1, #1
      bl      malloc

      mov      r1, r5
      mov      r2, r4
      mov      r3, r0
      pop      {r4, r5, lr}
      cmp r1, #8
      blo .Lscalar_loop

      mov      r12, #-128
      vdup.16      q1, r12
      mov      r12, #3
      vdup.16      q2, r12
      lsr      r12, r1, #3

.Lvector_loop:
      vld1.8      {d0}, [r2]!
      vaddw.u8      q0, q1, d0
      vshr.u16      q3, q0, #15
      vmul.i16      q0, q2
      vhadd.s16      q0, q3
      vst1.16      {q0}, [r0]!
      subs      r12, #1
      bne      .Lvector_loop

      and      r1, #7
      cbz      r1, 1f

.Lscalar_loop:
      # Fill in 8 instructions.

1:
      mov      r0, r3
      bx      lr
      .size      transform, .-transform

Скаларният цикъл нарочно е махнат.
PM
Top
AK-85
Публикувано на: 09-06-2018, 13:10
Quote Post



Име:
Група: Потребител
Ранг: Старо куче

Мнения: 748
Регистриран на: 06.07.06



Има малка грешка в горния код - според AAPCS (ABI-то) указателят към стека (т.е. SP) трябва да е подравнен на 8 байта при преминаване през публичен интерфейс като malloc(), така че в списъка на PUSH и POP може да се добави още един регистър, примерно R3, който да изпълни условието.
PM
Top
1 потребители преглеждат тази тема в момента (1 гости, 0 анонимни потребители)
Потребители, преглеждащи темата в момента:

Topic Options Reply to this topicStart new topicStart Poll

 


Copyright © 2003-2018 | BG Development | All Rights Reserved
RSS 2.0