Использование указателя стека (sp) в сборке руки

Меня немного смущает следующий фрагмент разборки:

_GSEventLockDevice:
000047d8        b5f0    push    {r4, r5, r6, r7, lr}
000047da        af03    add r7, sp, #12
000047dc        b08d    sub sp, #52
000047de    f7ffffb3    bl  _GSGetPurpleSystemEventPort
000047e2        466d    mov r5, sp
000047e4        2234    movs    r2, #52
000047e6        2100    movs    r1, #0
000047e8        4604    mov r4, r0
000047ea        4628    mov r0, r5
000047ec    f005e8b0    blx 0x9950  @ symbol stub for: _memset
000047f0        2600    movs    r6, #0
000047f2    f24030f6    movw    r0, 0x3f6
000047f6        4621    mov r1, r4
000047f8    e88d0041    stmia.w sp, {r0, r6}
000047fc        4628    mov r0, r5
000047fe    f7fffaf7    bl  _GSSendEvent
00004802        b00d    add sp, #52
00004804        bdf0    pop {r4, r5, r6, r7, pc}
00004806        bf00    nop

Я не понимаю, как это будет работать на C. Единственное, что я получаю, это:

memset(whateverTheStackPointerIs, 0, 52);

Но откуда мне знать, что такое sp и как это будет выглядеть в C?


person Johnathon    schedule 14.08.2011    source источник


Ответы (1)


То

sub sp, #52

резервирует 52 байта места для локальных переменных в стеке; после этого sp будет указывать на первый из этих 52 байтов. Затем все они обнуляются вызовом memset. После memset stmia сохраняет определенные значения в первых двух словах. Таким образом, эквивалент C будет чем-то вроде

GEEventLockDecvice() {
    int tmp = GSGetPurpleSystemEventPort();
    int localdata[13] = {0};
    localdata[0] = *0x3f6;
    localdata[1] = 0;
    return GSSendEvent(&localdata, tmp);
}
person hmakholm left over Monica    schedule 14.08.2011
comment
+1 выглядит довольно правдоподобно. Однако *0x3f6 не является допустимым C. Думаю, в данном случае должно быть *(volatile uint16_t*)0x3f6. Или он загружает 32-битные значения, а затем uint32_t. - person user786653; 14.08.2011
comment
Я думаю, что .w на ARM означает 32 бита. 16 бит были бы полусловом на жаргоне ARM. - person hmakholm left over Monica; 14.08.2011
comment
Когда бы вы использовали стек вместо регистров? - person Johnathon; 14.08.2011
comment
Когда у вас недостаточно регистров, чтобы хранить все. Или когда, как здесь, вы вызываете что-то, что требует указатель на ваши данные. У вас не может быть указателя на регистры. - person hmakholm left over Monica; 14.08.2011
comment
Спасибо, это работает отлично. Но при объявлении GSSendEvent, как я могу заставить его принимать указатель массива int? Я попробовал void GSSendEvent(int *data, mach_port_t port), но это не сработало. В качестве временного решения у меня просто есть void GSSendEvent(...) - person Johnathon; 14.08.2011
comment
Что касается семантики C, &localdata создает указатель на массив int, а не просто указатель на int. Это не важно для понимания ассемблера. Имейте в виду, что я не уверен, что это на самом деле массив int. Вероятно, это какая-то структура; по сборке не скажешь. Попробуйте погуглить GSSendEvent. - person hmakholm left over Monica; 14.08.2011
comment
Хорошо спасибо. Все уладил. Но что с третьей строкой (вторая строка сборки), где r7 назначается указателю стека + 12. Я не вижу, где это когда-либо использовалось, и кажется немного бессмысленным - person Johnathon; 14.08.2011
comment
Да, это выглядит бессмысленно. По-видимому (насколько я могу гуглить) r7 используется для оптимизации доступа к локальным переменным в некоторых инструкциях большого пальца. Возможно, компилятор просто инициализирует его по общим принципам и недостаточно умен, чтобы заметить, что на самом деле он его не использует. - person hmakholm left over Monica; 14.08.2011
comment
Обратите внимание, что этот код thumb2 не код ARM. ARM компания да, ARM вариант набора инструкций нет. thumb2 — часть большого пальца с расширениями thumb2. 32-битные инструкции, такие как movw, являются инструкциями thumb2. за исключением того, что есть несколько 32-битных инструкций перехода. ARM (компания) определяет слово как 32-битное, полуслово как 16-битное. mov rd,#immed, кодировка T1, дает 8 бит немедленного, T2 mov.w rd,#const 12 бит немедленного дает некоторые интересные 32-битные комбинации, T3 movw rd,#imm16 дает 16 бит немедленного, 0x3F6 будет и делает здесь попадают в кодировку Т3 - person old_timer; 14.08.2011
comment
infocenter.arm.com вниз по левой архитектуре ARM, щелкните справочные руководства, а затем, возможно, ARMv7-M, чтобы получить набор инструкций thumb/thumb2 (и другую информацию thumb2). - person old_timer; 14.08.2011