Como sé que a muchos les puede hacer falta, lo posteo acá y que cada cual saque sus conclusiones. Pongo la primera parte. Perdonen los errores en la descripción que pudieran haber.
---------------------------------------------------------------------
AND estándar
Un AND o que dos condiciones o subconjuntos de condiciones se den a la vez implica que si una de ellas no es positiva se salta directamente. Por lo que son dos condiciones con salto seguidas.
Código C++:
Ver original
if (c > b && b > a)
mov eax,dword ptr [c]
cmp eax,dword ptr [b]
jle main+56h (01124F76h)
mov eax,dword ptr [b]
cmp eax,dword ptr [a]
jle main+56h (01124F76h)
Se compara b con c, y si es negativo se salta a main+56h. Si es positivo se continua comparando a con b y si es negativo se salta a main+56. Si ninguno de los dos anteriores son positivos no se salta, y se continua con la ejecución. Dos comprobaciones negativas.
OR inclusivo (estándar)
Un or inclusivo implica que la condición es verdadera si uno de ellos es verdadero. De modo que con que la primera condición evaluada sea verdadera se salta. Si no es verdadera se comprueba la segunda, y si no es verdadera entonces es cuando se salta, y si no, se continua. Son entonces dos comprobaciones, comprobación positiva y una negativa.
Código C++:
Ver original
if (c > b || b > a)
mov eax,dword ptr [c]
cmp eax,dword ptr [b]
jg main+43h (013C4F63h)
mov eax,dword ptr [b]
cmp eax,dword ptr [a]
jle main+56h (013C4F76h)
Or exclusivo
El operador exclusivo XOR no existe en C++ por lo que es una lógica simulada.
c > b XOR b > a
!(c > b) || !(b > a)
La conversión se produce correctamente porque el operando ! convierte en false cuando hay una salida true, entonces, si los dos operandos son ciertos los dos son negativos. Un operando ! sobre todo el conjunto daría la salida contraria continuamente así que debe ser aplicado a cada subconjunto. Entonces, finalmente, cada una de las salidas sería una positiva y otra negativa salvo cuando los dos fueran positivas.
mov eax,dword ptr [c]
cmp eax,dword ptr [b]
jle main+43h (0964F63h)
mov eax,dword ptr [b]
cmp eax,dword ptr [a]
jg main+56h (0964F76h)
Las instrucciones de comparación son contrarias. La primera salta si es menor, por lo que no permite una segunda comprobación. Si es negativa continua para verificar si la segunda es correcta; si no es correcta salta a otro punto, y si no, continua ejecutando. Una negativa y otra positiva.
Do-while sin operaciones en do
Código C++:
Ver original
do{ } while(b > a);
mov eax,dword ptr [b]
cmp eax,dword ptr [a]
jg main+33h (0FA4D03h)
Tras comprobar la superioridad de b sobre a, se establece la condición del salto. El salto es hacia la dirección de memoria 0FA4D03h, que corresponde con la primera instrucción (mov eax, dword ptr [b]), para volver a comprobar.
La variable b (el valor de b) se vuelve a introducir en eax, ya que podría haber cambiado.
Do-while con instrucción en do
Código C++:
Ver original
do{ d++; } while(b > a);
mov eax,dword ptr [d]
add eax,1 mov
dword ptr [d],eax
mov eax,dword ptr [b]
cmp eax,dword ptr [a]
jg main+3Ah (01294D0Ah)
Al ser una instrucción do-while, do se realiza aunque no se haya comprobado la condición de while, de modo que las primeras 3 instrucciones se encargan de preincrementar la variable d. Y en la cuarta se procede a realizar la comprobación (si b es superior a a), si es superior se salta a la primera instrucción (01294D0Ah) nuevamente para realizar el mismo procedimiento.
Bucle for
Código C++:
Ver original
for (int i = 0; i < 1000; i++) { d++ }
mov dword ptr [ebp-38h],0
jmp main+4Ch (011D4D1Ch)
mov eax,dword ptr [ebp-38h]
add eax,1
mov dword ptr [ebp-38h],eax
cmp dword ptr [ebp-38h],3E8h
jge main+60h (011D4D30h)
mov eax,dword ptr [d]
add eax,1
mov dword ptr [d],eax
jmp main+43h (01A4D13h)
1. Lo primero que se hace es introducir el 0 en el registro que apunta (ebp-38h = 0x0040f8b4). La operación jmp probablemente venga precedida por alguna comprobación anterior, por lo que se ignora. Se introduce el 0 en eax y se le suma 1 para volverlo a introducir en el mismo registro. Se compara el registro con 3E8h (1000) y si es mayor o igual se salta a main+60h (coincide con while), si no, se continua con el segundo conjunto.
2. El segundo conjunto mueve d a eax y le incrementa 1 para volverlo a introducir en d. (d++)
3. El tercer conjunto salta inincondicionalmente a la tercera operación del primer conjunto, justo donde se mueve el puntero a eax para sumarle uno. ( } )
Se aprecian dos cualidades:
- La variable i del bucle no se almacena como ningún puntero ([i]) sino que se almacena como ebp-38h y se referencia directamente a esa dirección.
- En un inicio se incrementa i de 0 a 1 antes de realizar la comprobación de si es mayor o menor, de modo que continuamente se incrementa antes de realizar la comprobación.