ARM сдвиг влево или арифметическое вправо в зависимости от знака счетчика сдвигов для эффективного умножения на любую степень 2 - PullRequest
0 голосов
/ 01 марта 2019

Мы недавно начали изучать ассемблерный код, и у нас есть домашнее задание по этой теме.Мы изучали ARM и должны писать в Raspberry Pi.Один из моих домашних заданий читается так:

Напишите функции сборки, которые реализуют следующие функции C:

int32_t shiftS32 (int32_t x, int32_p) // return x * 2 ^ pдля p = -31..31

Это мой ответ на вопрос:

.global shiftS32  
.text  

shiftS32:  

PUSH {R0}   
CMP R0, #0   
BMI ENDA 
PUSH {R1}  
CMP R1, #0    

BMI END1   
POP {R1}  
MOV R0, R0, LSL R1  

BX LR

END1:
POP {R1}
SUB R1, #0
NEG R1, R1
MOV R0, R0, LSR R1 

BX LR

ENDA: 
PUSH {R1}
CMP R1, #0

BMI END 
POP {R1}
MOV R0, R0, LSL R1

BX LR

END:
POP {R1}
SUB R1, #0
NEG R1, R1
MOV R0, R0, ASR R1 

BX LR

Этот код работает, но, думаю, я переусердствовал с этим. Есть ли способ сделать то же самое, но в несколько строк?

1 Ответ

0 голосов
/ 01 марта 2019

Да, это слишком много кода.

Вы хотите использовать этот трюк для реализации целочисленного деления со знаком с точки зрения сдвигов при сохранении семантики округления n / 2 (в сторону 0), в отличие от сдвигов, которые округляются в сторону -infinity.

Вы, вероятно, хотите использовать условное выполнение.

Ваш код может быть коротким, как this :

shiftS32:
        cmp     r1, #0
        asrlt   r2, r0, #31
        addlt   r3, r1, #32
        lslge   r0, r0, r1
        rsblt   r1, r1, #0
        addlt   r0, r0, r2, lsr r3
        asrlt   r0, r0, r1
        bx      lr

И немного теста здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...