volatile
или нет, только технической причины EAX
бы должны быть инициализированы непосредственно перед выполнением вызова функции на Windows, были если function
объявлен __syscall
, т.е. используя соглашение о вызовах для Windows CS_SYSCALL. Понятно, что это немного похоже на соглашение UN * X x86_64, где %al
содержит количество аргументов типа с плавающей запятой, прошедших в регистрах %xmm
.
Конвенция о вызовах вызова вызова в ОС Windows идентична __cdecl
, то есть функции args на стеке в обратном порядке, но с добавлением, что AL
содержит счетчик количества аргументов; это делается так, что код ядра, который обычно находится на последнем конце, знает, сколько данных нужно считывать из стека пользователя в стек ядра для извлечения аргументов.
EAX
является регистром царапин для всех соглашений о вызовах на 32-битной Windows, его значение никогда не сохраняется по функциональным вызовам, инициализируя его непосредственно перед выполнением вызова, является избыточным. Даже если переменная, которую она держит, равна volatile
, потому что простая перезагрузка не является барьером памяти и не «фиксирует» предыдущий магазин. Кроме того, местоположение [EBP - 4]
находится в стеке , поэтому переменная местная (и определитель практически не имеет смысла).
Если это не пропустил оптимизации, то это может быть отсылкой к __syscall function(...)
с различным числом аргументов, как, гипотетически,
__syscall printf_syscall_conv(char *fmt, ...);
void possibly_print_three_vals(char *fmt, int val1, int val2, int val3)
{
if (*strchr('%', fmt) == '\0') // if no "%" in fmt, pass no args
printf_syscall_conv(fmt);
else
printf_syscall_conv(fmt, val1, val2, val3);
}
Это, вероятно, может создать выход сборки, как ваша.
Я видел, как компиляторы делали что-то глупое, чем это ... – Mysticial
@Mysticial: О, лол ... я впервые заметил что-то подобное. :) Хорошо знать. – Mehrdad
Возможно, есть ветка в первый толчок. –