Вторая часть просто указатель на функцию с инициализаторе (литье &puts
).
Первая часть более интересна:
Он получает %esp
в переменную C, и маски от младших 24 бит. то есть округляется до границы 16MiB. ИДК, что это для, но 4B смещение от вызова не-встраиваемой функции может или не вопрос (если %esp
был очень близко к границе 16MiB, или это явно то, что вы пытаетесь обнаружить.)
версия, опубликованная в вопросе, будет нарушать ваш код неочевидными способами, если компилятор когда-либо получит возможность встроить его в (например, с кросс-файловым вложением). Вместо правильного объявления выходного операнда из оператора asm
он просто изменяет %eax
внутри функции без оператора возврата. Это действительно глупо и имеет нулевые преимущества по сравнению с сообщением компилятору о том, что вы возвращаете.
/********* Safe version of the function *************/
// Actually unsigned long was fine, since this asm only works on 32bit anyway
static inline uintptr_t get_sp(void) {
uintptr_t result;
__asm__("movl %%esp, %0\n\t"
: "=g" (result)
);
result &= 0xff000000; // do this outside the inline asm so the compiler knows that the low 24b are always zero.
return result;
}
Это compiles to the same asm when not inlined, но может быть безопасно встраиваемыми. (например, поместите его в заголовок с static inline
). Он также, конечно, избегает предупреждений компилятора о функциях с отсутствующими возвращаемыми значениями.
Как отмечает Майкл Пётч в комментариях, включение этой функции всегда или внутри, или даже макроса, вероятно, является хорошей идеей для согласованности. (Хотя оптимизирован по сравнению с не-оптимизированные сборки будет потреблять разное количество стека в любом случае.)
Смотрите inline-assembly тег вики больше о том, как писать GNU C встроенный ассемблер, который не сосет.
Возможный дубликат [Как работают указатели функций в C?] (http://stackoverflow.com/questions/840501/how-do-function-pointers-in-c-work) –
@TalhaIrfan: Этот вопрос отвечает только на половину вопроса. Функция 'get_sp()' не объясняется и IMHO не является дубликатом этого. –
@MichaelPetch Я думаю, что ты прав Майкл. Я редактирую вопрос, чтобы связать его с get_sp() –