Когда должен флаг переноса быть установленным в ассемблере

Я озадачен этой проблемой при записи средства моделирования блока ARM в C. Я нашел некоторые подобные вопросы на форуме, но ни один из них не объясняет, как установить флаг переноса просто с помощью отношений между двумя операндами и результатом.

Любой ответ ценится.Заранее спасибо.

Отношение.

8
задан Paul R 18 May 2010 в 07:48
поделиться

4 ответа

Вы должны проверить справочное руководство для процессора, чтобы узнать, какие инструкции устанавливают флаги переноса и каким образом. Я недостаточно знаю об ARM, но я видел некоторые варианты в других процессорах:

  • некоторые инструкции, которые логически генерируют перенос, могут не устанавливать флаг переноса

  • некоторые инструкции могут использовать флаг переноса в качестве дополнительных неявный операнд или результат без связи со сложением / вычитанием

  • после вычитания процессоры различаются, в каком состоянии установлен флаг переноса (то есть некоторые делают это так же, как после добавления инвертированного второго операнда, другие установите его на отрицание этого)

Если вам нужен способ увидеть, нужно ли генерировать перенос для добавления в C, вот два способа (первый прямо из определения, второй исходит из обертывания поведение беззнакового):

unsigned w1, w2, result;
int carry;

carry = w1 > UINT_MAX-w2;

result = w1 + w2;
carry = result < w1;
4
ответ дан 5 December 2019 в 10:39
поделиться

Флаг переноса устанавливается обычным способом, например в результате сложения, генерирующего перенос. Затем вы можете использовать команду ADC (добавить с переносом), чтобы передать этот перенос в слово высокого порядка, напримерпри выполнении 64-битного сложения:

ADDS    r4, r0, r2    ; add least significant words
ADC     r5, r1, r3    ; add most significant words with carry

В этом примере 64-битное значение в r4: r5 равно сумме 64-битных значений в r0: r1 и r2: r3.

В ранних версиях ARM флаг переноса можно было установить явно следующим образом:

ORRS R15,R15,#&20000000

или так:

TEQP R15,#&20000000

Дополнительную информацию см. В этом руководстве: http: // www. peter-cockerell.net/aalp/html/ch-3.html

Очевидно, в более новых версиях ARM флаг переноса был перемещен в другой регистр (см. комментарии ниже).

6
ответ дан 5 December 2019 в 10:39
поделиться

Обратитесь к Справочному руководству по архитектуре ARM (именуемому «ARM ARM»). В наши дни вам может понадобиться логин, но он бесплатный (сразу после соглашения «Обещание не подавать на нас в суд»).

ARM ARM имеют подробную информацию о том, когда бит C устанавливается и очищается для каждой инструкции в форме псевдокода. В ARMv5 ARM для ADCS у вас есть, например,

C Flag = CarryFrom(Rn + shifter_operand + C Flag)

... и они охватывают инструкции набора команд ARM и Thumb.

(Вы заметите, что почти все арифметические инструкции в режиме большого пальца всегда устанавливают флаги кода условия, включая бит переноса; в режиме ARM обычно этого не происходит, если для них не установлен флаг S.)

(Также , моя информация может быть устаревшей; я больше всего знаком с архитектурой ARMv5TE.)

3
ответ дан 5 December 2019 в 10:39
поделиться

посмотрите на армулятор, который вы можете найти в исходниках gdb.

Для добавления двух операндов вы можете определить по старшим битам операндов и результату, был ли перенос. Или вы можете написать экспериментальный, скажем, 8-битный сумматор и построить таблицу истинности.

РЕДАКТИРОВАТЬ:



#include <stdio.h>

#define BITS 2
#define MASK ((1<<BITS)-1)

unsigned int ra,rb,rc;

int main ( void )
{

    for(ra=0;ra<=MASK;ra++)
    {
        for(rb=0;rb<=MASK;rb++)
        {
            rc=ra+rb;
            printf("%u + %u = %u : %u %u %u : %u\n",ra,rb,rc,((ra>>(BITS-1))&1),((rb)>>(BITS-1))&1,((rc>>(BITS-1))&1),rc>>BITS);
        }
    }
    return(0);
}

Что дает:

0 + 0 = 0 : 0 0 0 : 0
0 + 1 = 1 : 0 0 0 : 0
0 + 2 = 2 : 0 1 1 : 0
0 + 3 = 3 : 0 1 1 : 0
1 + 0 = 1 : 0 0 0 : 0
1 + 1 = 2 : 0 0 1 : 0
1 + 2 = 3 : 0 1 1 : 0
1 + 3 = 4 : 0 1 0 : 1
2 + 0 = 2 : 1 0 1 : 0
2 + 1 = 3 : 1 0 1 : 0
2 + 2 = 4 : 1 1 0 : 1
2 + 3 = 5 : 1 1 0 : 1
3 + 0 = 3 : 1 0 1 : 0
3 + 1 = 4 : 1 0 0 : 1
3 + 2 = 5 : 1 1 0 : 1
3 + 3 = 6 : 1 1 1 : 1

Очевидный случай, когда установлены msbit первого операнда и msbit второго операнда, вы собираетесь перенести этот бит. Два менее очевидных случая: когда msbit a установлен, а msbit результата не установлен, был перенос, аналогично, когда msbit b установлен, а msbit результата не установлен, был перенос .

Итак

carry=0
if((MSB(A))&&(MSB(B))) carry=1
if((MSB(A))&&(!MSB(ANS))) carry=1
if((MSB(B))&&(!MSB(ANS))) carry=1
3
ответ дан 5 December 2019 в 10:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: