ARM Condition Codes

Тема в разделе "WASM.ASSEMBLER", создана пользователем cppasm, 24 фев 2010.

  1. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Привет.
    Кто занимался ассемблером ARM, подскажите в чём разница между следующими кодами условий:
    HS Unsigned higher or same
    PL Plus/positive or zero

    Как по мне - одно и то же. Но флаги разные проверяет.
    Для каких инструкций есть разница между этими кодами условий?
     
  2. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    cppasm
    PL проверяет знаковый бит N. HS проверяет бит переноса C. В этом собсно и разница. Аналогично в x86 SF и CF. Или между ними тоже разницу объяснить надо? :)
    Пример инструкции... ну скажем сложили два беззнаковых числа. Получили большое число (достаточно, чтобы как знаковое оно было отрицательным). При этом N будет выставлен, но, т.к. переноса не было, C будет сброшен. Или тот же ADC работает с C, а не с N.
     
  3. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    cppasm
    Что-то меня увело в сторону различий между C и N вместо HS и PL. И пример соответственно получился не показательным. С другой стороны по аналогии можно придумать все четыре возможных комбинации для флагов C и N:
    1) Сложение двух небольших чисел (10 и 15, например): нет переполнения, нет достижения диапазона отрицательных.
    Соответственно C = 0, N = 0.
    2) Сложение 98CA C92B и 9B1 4D22: нет переполнения, но результат в диапазоне отрицательных.
    Соответственно C = 0, N = 1.
    3) Сложение 98CA C92B и 98CA C92B: переполнение, но результат в диапазоне положительных.
    Соответственно C = 1, N = 0.
    4) Сложение 98CA C92B и FFFF FFFF: переполнение и результат в диапазоне отрицательных.
    Соответственно С = 1, N = 1.

    Вывод: HS и PL, равно как и флаги, ими проверяемые, ни разу друг от друга не зависят. Откуда взялось: "Как по мне - одно и то же", — непонятно.
     
  4. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Ну начнём с того что в ARM C=1 если заёма не было, и 0 - если был.
    HS - C=1 (заёма не было)
    PL - N=0
    Теперь откуда взялось.
    К примеру CMP R0, #0x20
    Это установка флагов для R0-0x20.
    Получается
    C=1 когда R0>=0x20
    N=0 когда R0>=0x20
    В чём проблема я уже понял.
    При проверке флага C R0 надо рассматривать как беззнаковое, а для N - как знаковое.
    Т.е. при R0=-1 при CMP R0, #0x20 будет C=1 (0xFFFFFFFF>=0x20), N=1 (-1<0x20, 0xFFFFFFFF-0x20=0xFFFFFFDF - знаковое).
    В общем-то я ещё простой пример нашёл :)
    MOV R0, 1, LSL 31 - число отрицательное, а переноса нет.
     
  5. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Просто вот простой пример.
    Самая дубовая функция:
    Код (Text):
    1. void copy(int *dst, int *src, int size)
    2. {
    3.     while(size>=sizeof(int))
    4.     {
    5.         *dst++ = *src++;
    6.         size-=sizeof(int);
    7.     }
    8. }
    Компилируем GCC, получаем:
    Код (Text):
    1.     .file   "test.c"
    2.     .text
    3.     .align  2
    4.     .global copy
    5.     .type   copy, %function
    6. copy:
    7.     @ args = 0, pretend = 0, frame = 0
    8.     @ frame_needed = 0, uses_anonymous_args = 0
    9.     @ link register save eliminated.
    10.     cmp r2, #3
    11.     bxls    lr
    12.     mov r3, #0
    13. .L3:
    14.     ldr ip, [r1, r3]
    15.     str ip, [r0, r3]
    16.     add r3, r3, #4
    17.     rsb ip, r3, r2
    18.     cmp ip, #3
    19.     bhi .L3
    20.     bx  lr
    21.     .size   copy, .-copy
    Вопрос - почему вторая команда bxls?
    Ведь LS - это unsigned higher or same (Z=1 or C=0), а у size тип знаковый.
    Т.е. если я передам в size (-1) то работать будет неправильно, или я чего-то не понимаю?
     
  6. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    cppasm
    Неважно, какой именно ассемблер, логика у всех одинаковая, только мнемоники и некоторые особенности отличаются.

    PL -- это проверка знакового бита (старшего разряда числа со знаком), а HS -- флага переноса после команд вычитания или сравнения, поскольку именно он для _беззнаковых_ операндов показывает, кто был больше.
     
  7. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    cppasm
    Эм... во-первых, я говорил о переносе. И там C выставляется как раз тогда, когда перенос произошёл.
    Во-вторых... ну и что? Если Вам известно назначение CF и SF в x86, то в ARM аналогично. То, что в случае заёма C в ARM не выставляется, сути не меняет, т.к. назначение флага идентично CF в x86.
    Ну... LS - это вообще-то lower or same. :derisive: Да... у size тип знаковый. А какой тип у результата работы sizeof? :derisive: Неявное приведение типа. Думаю, если все sizeof'ы позаменять на 4, то bxls и bhi превратятся в знаковые условия.
     
  8. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    дык sizeof() это compile-time оператор, и он, если ничего не путаю, должен давать тот же эффект что и размер написанный как константа.
     
  9. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Ну не знаю, у меня на х86 вопросов не вызывало как-то...
    А тут инвертированный флаг переноса напрягает.
    По-моему как раз нет.
    Вот к примеру описания из официального мануала.
    CMP:
    SBC:
    Кругом инверсия.
    Да, это я перепутал (опечатка) - unsigned lower or same.
    Да, так и есть. Не обратил внимания...
    Неа. Он возвращает size_t.
    А числовые константы по умолчанию имеют тип int если в него влезают.
    Аналогом sizeof(int) на 32-битной платформе будет 4u, а не 4.
     
  10. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    cppasm
    Дык SBC и CMP - это вычитание. :) Там заёмы, а не переносы. А переносы в ADD и CMN, для которых в случае беззнакового переполнения C будет выставляться.
     
  11. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    cppasm
    Это больше дело привычки, сложностей как таковых нет. Правда, есть риск запутаться из-за подобных вещей, так что надо быть внимательным...
     
  12. cppasm

    cppasm New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    923
    Блин точно.
    У ADD - как раз привычное использование C, и в ADC используется прямое значение.
    В общем мне как оказалось проще рассматривать С как 33-й бит первого операнда, установленный в 1 для команд вычитания (не было заёма он 1, если был - 0) и в 0 для сложения (не было переполнения он 0, было - 1).
    Так сложностей ни в чём нет если разобраться.
    Но вот на х86 CF одинаково работает как для заёма, так и для переполнения.
    А в ARM вот по другому. Лучше видно в мануал поглядывать :)
     
  13. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    fasmarm +доки:
    http://arm.flatassembler.net/

    топик по fasmarm:
    http://board.flatassembler.net/topic.php?t=4191

    автор fasmarm:
    revolution, http://board.flatassembler.net