Реализация кода ASM для умножения целого числа - PullRequest
0 голосов
/ 09 октября 2019

Следующий код ASM используется для нахождения произведения двух целых чисел путем запроса ввода от пользователя.

Какова цель реализации этих следующих строк кода?

MOVNE R2, R2, LSL #1 
MOVNE R4, R4, LSL #1
TST R1, R4

Полный код:

.global multiply

.text

multiply:
    MOV R2, R0 
    MOV R0, #0 
    MOV R3, #0 
    MOV R4, #1
loop:
    CMP R3, #0 
    MOVNE R2, R2, LSL #1 
    MOVNE R4, R4, LSL #1
    TST R1, R4
    BEQ iterate
    ADD R0, R0, R2

iterate:
    ADD R3, R3, #1
    CMP R3, #31
    BLE loop

exit:
    BX LR

1 Ответ

1 голос
/ 09 октября 2019

Я предполагаю, что вы уже знаете, что, например, 3 * 11 можно переписать как 3 * 1 + 3 * 2 + 3 * 8. Эта последняя форма в основном соответствует тому, как код, который вы опубликовали, используется для вычисления результата.

Вы получили множитель и множитель в R0 и R1;давайте назовем их X и Y, а также битовое число (0..31) в R3;давайте назовем это N.

Так что для каждого значения N вы вычисляете X << N, то есть X * 2^N. Это действительно то, что делает CMP R3, #0 / MOVNE R2, R2, LSL #1. Сдвиг - это всего лишь один сдвиг влево, то есть удвоение текущего значения, но поскольку вы делаете это для каждой итерации, кроме первой, вы в итоге получаете X << N.

Затем вы проверяете, если N th бит Y установлен:

(CMP R3, #0 )
MOVNE R4, R4, LSL #1     @ R4 = 1 << N == 1 * 2^N
TST R1, R4               @ Set flags based on Y & (1 * 2^N)

Если N th бит Y был установлен , вы добавляете X << N к результату. Затем повторите для следующего значения N и т. Д.

В случае 3 * 11 (двоичный 0011 * 1011) у вас есть биты 0, 1 и 3, установленные в Y,так что вы получите результат (3 << 0) + (3 << 1) + (3 << 3) == 3*1 + 3*2 + 3*8 == 3 + 6 + 24 == 33.

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