volatile
o no, la única técnica razón por la cual habría EAX
tenga que ser inicializado directamente antes de hacer una llamada a la función en Windows eran si eso function
se declara __syscall
, es decir, utilizando la convención de llamada de Windows CS_SYSCALL. Conceptualmente, esto es un poco similar a la convención UN * X x86_64 donde %al
contiene la cantidad de args de tipo de punto flotante pasados en los registros %xmm
.
La convención de llamadas syscall en Windows es idéntica a __cdecl
, es decir, funciona args en la pila en orden inverso, pero con la adición de que AL
contiene un recuento de la cantidad de argumentos; esto se hace para que el código del kernel, que generalmente se encuentra al final de este, sepa cuántos datos leer del usuario se apilan en la pila del kernel para recuperar los args.
EAX
es un registro de arañazos para todas las convenciones de llamadas en Windows de 32 bits, su valor nunca se preserva con las llamadas a funciones, inicializándolo directamente antes de hacer una llamada es redundante. Incluso si la variable que contiene es volatile
, porque una simple recarga no es una barrera de memoria y no "confirma" una tienda anterior. Además, la ubicación [EBP - 4]
está dentro de la pila , por lo que la variable es local (y un calificador volatile
tiene poco sentido).
Si no es una optimización perdido, entonces podría ser una invocación de un __syscall function(...)
con diferente número de argumentos, como, hipotéticamente,
__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);
}
Esto podría crear concebible salida de montaje como la suya.
He visto compiladores haciendo cosas más tontas que esta ... – Mysticial
@Mysticial: Oh lol ... es la primera vez que noté algo como esto. :) Bueno saber. – Mehrdad
Quizás haya una rama en el primer empujón. –