LINUX.ORG.RU

В чем смысл ARMовской конструкции?

 ,


0

1

Изучаю ARM ассемблер, в дизассемблированом коде периодически встречаются конструкции вида

.text:01700AD0                 STR             R3, [SP,#0x98+var_48]
.text:01700AD4                 LDR             R1, [R3]
.text:01700AD8                 ADD             R11, R2, R11
.text:01700ADC                 CMP             R1, #0
.text:01700AE0                 BEQ             loc_1700B08
.text:01700AE4                 CMN             R1, #1
.text:01700AE8                 BEQ             loc_1700B08
.text:01700AEC                 DMB             SY
Хочется узнать в порядке повышения общей эрудиции, каков сакральный смысл их и когда их можно применять самому?


Армовские команды, я понимаю. А слева их адреса в шестнадцатиричном виде. А .text видимо обозначает сегмент кода.

aureliano15 ★★
()
Ответ на: комментарий от Puzan

Похоже, что ТС все-таки интересует, в чем смысл именно приведенной последовательности команд, так как она часто встречается в коде.

zloy_starper ★★★
()

Откуда этот код?

Вообще это сравнение R1 с 0 и -1, похоже на проверку какого-то результата.

alexru ★★★★
()

Это инициализация функции вот пример

// Type your code here, or load an example.
int square(int num) {
    return num * num;
}
а вот что после компилятора
square(int):
  str fp, [sp, #-4]!
  add fp, sp, #0
  sub sp, sp, #12
  str r0, [fp, #-8]
  ldr r3, [fp, #-8]
  ldr r2, [fp, #-8]
  mul r3, r2, r3
  mov r0, r3
  add sp, fp, #0
  ldmfd sp!, {fp}
  bx lr

Silerus ★★★★
()
Ответ на: комментарий от Silerus

Какое отношение этот код имеет к исходному вопросу?

alexru ★★★★
()

И судя по DMB - это рукописный код, так что можно посмотреть на исходник. Может там комментарии есть.

alexru ★★★★
()
Ответ на: комментарий от alexru

Нет, по видимому, это именно компилятор упорно добавляет этот фрагмент чуть менее,чем всюду. Вот более длинный фрагмент кода. Обратите внимание на то, куда ведут ссылки при равенстве 0 и -1

                BL              _ZN5QListIiED1Ev ; QList<int>::~QList()
                LDR             R3, [R4,#-8]
                LDR             R2, [R3]
                CMP             R2, #0
                BNE             loc_1FA294

loc_1FA280                              ; CODE XREF: sub_1FA250+6C↓j
                LDR             R0, [R4,#-8]
                MOV             R1, #2
                MOV             R2, #4
                BL              _ZN10QArrayData10deallocateEPS_jj ; QArrayData::deallocate(QArrayData*,uint,uint)
                B               loc_1FA2C0
loc_1FA294                              ; CODE XREF: sub_1FA250+2C↑j
                CMN             R2, #1
                BEQ             loc_1FA2C0
                DMB             SY

loc_1FA2A0                              ; CODE XREF: sub_1FA250+60↓j
                LDREX           R2, [R3]
                SUB             R2, R2, #1
                STREX           R1, R2, [R3]
                CMP             R1, #0
                BNE             loc_1FA2A0
                CMP             R2, #0
                DMB             SY
                BEQ             loc_1FA280

loc_1FA2C0                              ; CODE XREF: sub_1FA250+40↑j
                                        ; sub_1FA250+48↑j
                ADD             R4, R4, #0x18
                B               loc_1FA25C

MBK
() автор топика
Ответ на: комментарий от MBK

Ну и где тут код из первого поста? Понятно, что компилятор будет добавлять, но это выглядит как нормальный код. Что в исходнике-то?

То, что некоторые инструкции часто встречаются вместе - это не случайность, это оптимизация - попытка раскидать их по разным конвеерам.

alexru ★★★★
()
Последнее исправление: alexru (всего исправлений: 1)
Ответ на: комментарий от alexru

Вы правда не видите аналогии? Хорошо, вот вам еще фрагмент:

                LDR             R2, [R3]
                CMP             R2, #0
                BEQ             loc_1FAE68
                CMN             R2, #1
                BEQ             loc_1FAE68
                DMB             SY

loc_1FAE50                              ; CODE XREF: sub_1FAC1C+244↓j
                LDREX           R2, [R3]
                ADD             R2, R2, #1
                STREX           R11, R2, [R3]
                CMP             R11, #0
                BNE             loc_1FAE50
                DMB             SY

loc_1FAE68                              ; CODE XREF: sub_1FAC1C+224↑j
Повторяю,откомпилированый код состоит из подобных проверок процентов на 60

MBK
() автор топика
Ответ на: комментарий от MBK

И что? Это может какие-то C++ заморочки. Нужно смотреть что в этом месте в исходнике. Чему этот R2 равен? И с какими параметрами компилятора собран бинарник?

Но если хочется просто так гадать на кофейной гуще, то продолжайте наблюдения.

Какой полный объем кода, если 60% такие проверки?

alexru ★★★★
()
Последнее исправление: alexru (всего исправлений: 1)

какой компилятор, какой версии, с какими опциями конпеляется (особенно по части оптимизации), подробности в студию

Harald ★★★★★
()
Ответ на: комментарий от MBK

DMB - барьер доступа к памяти (DMB SY ждёт когда все чтения и записи завершатся). Похоже на какой-то ввод/вывод.

slapin ★★★★★
()
Ответ на: комментарий от alexru

Исходника, разумеется, нет, иначе я бы и не начинал данный топик. Неясен так же и компилятор, объем кода очень велик. Гадание на кофейной гуще приводит к гипотезе, что это некая стандартная обработка QTшных объектов, хочется услышать от профессионалов, в чем ее логический смысл?

MBK
() автор топика
Ответ на: комментарий от MBK

Пары LDREX/STREX похожы на блокировку мютекса. Прошлый код скорее всего тоже к этому относится.

alexru ★★★★
()
Ответ на: комментарий от MBK

Нужно больше контекста тогда до этого места. Но скорее всего мютексы. Нужно хотя бы примерно найти место в исходниках Qt, чтобы посмотреть что они там делают так часто.

alexru ★★★★
()
Ответ на: комментарий от alexru

Ну хорошо, спасибо, с этим фрагментом понятно. Но меня все таки, больше интересует именно топиковая конструкция - «проверка на 0, - проверка на -1 - системный барьер» Какие идеи по этому поводу?

MBK
() автор топика
Ответ на: комментарий от MBK

Учитывая, что проверяется значение того-же семафора, это тоже какая-то операция над ним. Возможно проверка того, что он уже взят.

Нужно смотреть на остальной код и искать пары взятие-отпускание.

alexru ★★★★
()
Ответ на: комментарий от alexru

Ну вот например вход в процедуру:

                LDR             R3, [R1]
                STMFD           SP!, {R4-R7,LR}
                SUB             SP, SP, #0xC
                MOV             R7, R1
                MOV             R5, R0
                STR             R3, [SP,#0x20+var_1C]
                LDR             R2, [R3]
                CMP             R2, #0
                BEQ             loc_1703238
                CMN             R2, #1
                BEQ             loc_1703238
                DMB             SY

loc_1703220                             ; CODE XREF: sub_17031F0+40↓j
                LDREX           R1, [R3]
                ADD             R1, R1, #1
                STREX           R2, R1, [R3]
                CMP             R2, #0
                BNE             loc_1703220
                DMB             SY

loc_1703238                             ; CODE XREF: sub_17031F0+20↑j
                                        ; sub_17031F0+28↑j
                ADD             R6, SP, #0x20+var_1C
                MOV             R0, R5
                MOV             R2, SP
                MOV             R1, R6
                BL              sub_17008F0
Я правильно понимаю, что существует некий глобальный семафор, передаваемый сквозным образом всем процедурам через регистр R1?

MBK
() автор топика
Ответ на: комментарий от MBK

Нужно смотреть что там в коде Qt передается. Еще нужно смотреть какое соглашение о вызовах было использовано. Согласно AAPCS R1 содержит второй параметр. В случае C++ первым вероятно будет this.

Хотя если таким обернуты многие функции, то возможно это какая-то опция компилятора к такому приводит.

По смыслу похоже на поведение QMutexLocker. Можно в эту сторону смотреть. Если через R1 передался this и переменная QMutex первая в объекте, то код примерно так и должен выглядеть.

alexru ★★★★
()
Последнее исправление: alexru (всего исправлений: 2)

Очень похоже на реализацию __sync_fetch_and_add макроса, применяющегося при разработке lock-free алгоритмов.

#include <glib.h>
#include <glib/gprintf.h>
#include <glib/gatomic.h>

int main()
{
        volatile int var = 0;
        volatile int num = 1;
        g_printf("HI ARM\n");

        __sync_fetch_and_add(&var, num);

        return 0;
}

objdump -d ./a.out

0001057c <main>:
   ....
   1059c:       f3bf 8f5f       dmb     sy
   105a0:       e853 0f00       ldrex   r0, [r3]
   105a4:       4410            add     r0, r2
   105a6:       e843 0100       strex   r1, r0, [r3]
   105aa:       2900            cmp     r1, #0
   105ac:       d1f8            bne.n   105a0 <main+0x24>
   105ae:       f3bf 8f5f       dmb     sy
   105b2:       2300            movs    r3, #0
   105b4:       4618            mov     r0, r3
   105b6:       3708            adds    r7, #8
   105b8:       46bd            mov     sp, r7
   105ba:       bd80            pop     {r7, pc}
Dennis7
()
Ответ на: комментарий от alexru

Согласно AAPCS R1 содержит второй параметр. В случае C++ первым вероятно будет this.

Ну так и есть. Судя по дальнейшему коду, в качестве this используется передаваемый в процедуру R0/R5 А вот R1 похоже как специально передается вторым параметром для синхронизации?

Очень похоже на реализацию __sync_fetch_and_add макроса, применяющегося при разработке lock-free алгоритмов.

Похоже, да. И что это дает?

MBK
() автор топика
Ответ на: комментарий от MBK

А вот R1 похоже как специально передается вторым параметром для синхронизации?

Возможно используемый Mutex передается по указателю, а не как член класса.

Похоже, да. И что это дает?

Thread-safe код.

alexru ★★★★
()

В тех местах Qt, которые ты показал (QList::~QList и QArrayData::deallocate) освобождается память (в QArrayData явно зовут free()). Скорее всего, это синхронизация внутри стандартной библиотеки чтобы обеспечить многопоточность для heap (malloc/free, new/delete)

Kosyak ★★★★
()
Ответ на: комментарий от MBK

Изучаю ARM ассемблер

Исходника, разумеется, нет,

выше написали, повтопю- ты не «изучаешь», ты гадаешь на кофейной гуще

изучают любой ассемблер/дизасемблер компилянием хеловорда, и смотря результат, постененно переходя к более объемному коду чтоб составлять последовательность из шабллонных участков кода сгененированным компилятором

и да «изучание» по компилянию зеловорда займет пару дней
иучение «твоим методом» займет десятилетия

полагаю у тебя нет реальнойработы и ты маешься этим бредом

missxu
()
Ответ на: комментарий от missxu

полагаю у тебя нет реальнойработы и ты маешься этим бредом

Уважаемый, я задал конкретный вопрос и получил на него конкретный ответ от знающих людей. Собственно, за этим и задавал. А у вас, полагаю, нет реальной работы и вы маетесь флудом в уже закрытом топике.

MBK
() автор топика
Ответ на: комментарий от MBK

что ты блять несешь, какой конкретный вопрос? давай ты еще скопипастишь бинарный код и спросишь «знающих»(что блять) людей что он делает

не майся хуйней долбайоб

missxu
()
Ответ на: комментарий от missxu

Казалось бы чего сказал такого, а вононо как пригорело...

долбайоб

Необычная у вас подпись, она чтото означает?

MBK
() автор топика
Ответ на: комментарий от anonymous

Ну если бы был исходник, не было бы и топика.

Исходника, разумеется, нет, иначе я бы и не начинал данный топик. Неясен так же и компилятор

Хорошо, открою страшную тайну для тех, кто уж совсем в танке. Это реверс.

MBK
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.