Что делает этот код? (Ассемблер)
В коде, где тестируется работа таймеров SDL2, обнаружил следующий код:
int asmFunction (void)
{
static int internalValue = 1;
#ifdef __GNUC__
__asm__ ("movl %0, %%eax\n\t"
"add %%eax, %0"
: "=r" (internalValue)
: "r" (internalValue));
#elif _MSC_VER
_asm {
mov eax, internalValue
add internalValue, eax
};
#endif
return internalValue;
}
Вместе с запуском программы включается таймер на 15 секунд, а по прошествии времени вызывается следующая функции, и программа корректно завершает работу. Как установить таймер - мне понятно, но вызов функции с ассемблером мне не ясен:
Uint32 repeatOnceFunction (Uint32 interval, void * param)
{
SDL_Event exitEvent = { SDL_QUIT };
if (asmFunction() != 0)
{
SDL_HideWindow (static_cast <SDL_Window *> (param));
SDL_Delay (15000);
SDL_PushEvent (&exitEvent);
}
return 0;
}
При удалении вызова этой функции работа таймеров не меняется, разве что программа завершается резко по окончанию таймера, без паузы. Что же делает этот код?
Ответы (1 шт):
Ассемблер в данном случае просто осуществляет приращение переменной на её собственную величину:
movl %0, %%eax
add %%eax, %0
Помещает переменную internalValue в регистр, а затем прибавляет к нему значение internalValue. Так как internalValue статична, получается следующее:
asmFunction() // 2
asmFunction() // 4
asmFunction() // 8
Как справедливо заметил @avp, на системе с четырехбайтовым целочисленным, код будет выполнять условие != 0 только 31 раз, последующие итерации будут возвращать 0 из-за переполнения:
movl %0, %%tax ; 1000...0000 (-2147483648)
add %%eax, %0 ; 0
В коде, где тестируется работа таймеров SDL2, обнаружил следующий код
Нет, это не код, где тестируется таймер SDL2. Это кусок лабораторной работы.
Что же делает этот код?
Исходя из описания этой работы — вводит вас в заблуждение. Плюс, выполнение полной версии кода repeatOnceFunction из моей ссылки приведет к крашу, так как колбек таймера будет выполнен не в UI потоке. Скорее всего для этого и заморочки с asmFunction(), а исправление выглядит как-то так:
static int internalValue = 0;