Red de conocimientos sobre prescripción popular - Conocimiento de las drogas - Análisis en profundidad de por qué el resultado de printf es cero.

Análisis en profundidad de por qué el resultado de printf es cero.

Como se mencionó, hay dos razones:

1. El formato de almacenamiento y el diseño de los números enteros y de punto flotante en la memoria son diferentes (para conocer el diseño de la memoria y la representación de los números de punto flotante, consulte / songjin/article/details/7753777).

2. Al colocar parámetros en la pila, printf coloca los parámetros en la pila de acuerdo con el tipo de parámetros reales, no según el tipo especificado en el carácter de formato. El proceso de apilamiento específico es el siguiente. Como resultado, el tipo de parámetro colocado en la pila no coincide con el tipo utilizado por la función real (el punto clave es que el tamaño de la memoria ocupada es diferente), por lo que los resultados mencionados en la pregunta aparecerán durante el análisis específico, porque el El diseño de la memoria cuando la configuración se analiza en números de punto flotante será muy pequeño, porque la configuración se almacena originalmente en 4 bytes, pero se analiza en un número de punto flotante de 8 bytes, por lo que el valor obtenido será muy pequeño, al igual que el punto flotante. número: desnormalización: cuando todos los e Los bits binarios son todos 0, n

Tenga en cuenta que el bit oculto a la izquierda del punto decimal es 0. Por qué E es igual a (1-sesgo) en lugar de (-sesgo) está diseñado principalmente para una transición suave entre valores normalizados y desnormalizados. Continuaremos esta discusión más adelante.

En forma desnormalizada, podemos representar 0. Después de configurar el bit de signo S en 1 y configurar todos los demás bits en 0, obtenemos -0,0 de manera similar, si todos los bits se configuran en 0, obtenemos +0,0; Los números desnormalizados tienen otros usos, como representar decimales que están muy cerca de 0, y estos decimales están uniformemente cerca de 0, lo que se denomina propiedad de "desbordamiento gradual".

Los siguientes son dos fragmentos de código de desensamblado para analizar cómo se colocan los parámetros en la pila:

printf("%f ", 45);

00405028 mov esi, esp

0040502A push 2Dh

0040502 c push offset_ORDER_SERVER_ADDRESS-0 ach(43 F2 ach)

00405031 call dword ptr[_ _ imp _ _ printf(43c 124h)]

00405037 add esp, 8

printf("%f ", d); (d es una variable entera)

00405028 mov esi, esp

0040502A mov ecx, dword ptr [d]

0040502D push ecx

0040502 e push offset _ ORDER _ SERVER _ ADDRESS-0 ach (43 F2 ach)

00405033 call dword ptr[_ _ imp _ _ printf(43c 124h)]

00405039 add esp, 8

0040503C cmp esi , esp

0040503 e call _ RTC _ check esp(439760h)

Doble a=5, c;

Flotante b ;

int d=0x40a00000, y = 6;

int * p;

char s = 5;

p = & ampd;

b =(flotar)a;

printf("%f,%f,%f,%f,%f,%f,%d ",b, c, (flotar)d, s, (float)s, y, y);

00405028 mov esi, esp

0040502A mov ecx, dword ptr [y]

0040502D push ecx

0040502E mov edx, dword ptr [y]

00405031 push edx

00405032 movsx eax, puntero de byte [s]

00405036 mov dword ptr [ebp-34h], eax

00405039 campo dword ptr [ebp-34h]

0040503C bomba sumergible eléctrica, 8

p>

0040503F fstp qword ptr [esp]

00405042 movsx ecx, puntero de byte [s]

00405046 push ecx

00405047 puntero de palabra doble de campo [d]

0040504A sub-esp, 8

0040504D fstp qword ptr [esp]

00405050 sub-esp, 8

00405053 fld qword ptr [c]

00405056 fstp qword ptr [esp]

00405059 fld dword ptr [b]

0040505C electrobomba sumergible, 8

0040505F fstp qword ptr [esp]

00405062 push offset _ ORDER _ SERVER _ ADDRESS-0C4h (43 F2 ach)

00405067 call d

word ptr[_ _ imp _ _ printf(43c 124h)]

0040506D Añadir bomba sumergible eléctrica, 30h

00405070 cmp esi, esp

00405072 call _ RTC _ comprobar esp(439780h)