Que signifient ces paires d'instructions?


1

Je ne sais pas si c'est demandé mais, je n'ai rien trouvé malgré la question this. Est-ce à cause de la faute du désassembleur? Ou si c'est juste pourquoi le compilateur génère ce code?

; int __cdecl main(int argc, const char **argv, const char **envp) 
main   proc near    ; CODE XREF: start-7Bp 

var_4   = dword ptr -4 
argc   = dword ptr 8 
argv   = dword ptr 0Ch 
envp   = dword ptr 10h 

       push ebp 
       mov  ebp, esp 
       push ecx 
       call ds:GetCurrentProcessId 
       mov  [ebp+var_4], eax ; <--- 
       mov  eax, [ebp+var_4] ; <--- 
       push eax 
       push offset output 
       call printf 
       add  esp, 8 

debugger_wait:       ; CODE XREF: main+28j 
       call ds:IsDebuggerPresent 
       test eax, eax 
       jnz  short debugger_present 
       jmp  short debugger_wait 
; --------------------------------------------------------------------------- 

debugger_present:      ; CODE XREF: main+26j 
       int  3    ; Trap to Debugger 
       xor  eax, eax 
       mov  esp, ebp 
       pop  ebp 
       retn 
main   endp 

lignes avec des flèches marquées (de sortie IDA) montre deux opérations MOV qui équivaut sémantiquement à rien (ou est-il?). Ceci est mon code source:

#include <stdio.h> 
#include <Windows.h> 

int main(int argc, char *argv[], char *envp[]) 
{ 
    DWORD pid = GetCurrentProcessId(); 
    printf("%d\n", pid); 
    while (!IsDebuggerPresent()); 
    __asm int 0x3; 
    return 0; 
} 

Compilé avec MSVC++ (19.00.24225.1):

cl.exe dnmProg.c 

MISE À JOUR: J'ai essayé d'autres options et à la fois/O1 et/O2 n'a pas une telle structure, mais/Ot a la même paire d'instructions. Quand je compilé avec/S il y a:

call ds:GetCurrentProcessId 
mov  [ebp+var_4], eax ; <--- 
push [ebp+var_4]  ; <--- 
push offset printf_parameter 
call printf_ 

Merci.

  0

Si vous compilez en mode débogage, le compilrr enregistre normalement les valeurs de retour, il a donc sauvé eax à dwid pid et ensuite utilisé le pid enregistré pour printf 26 nov.. 172017-11-26 03:12:30

  0

Vous voulez dire le mode de débogage de Visual Studio? J'ai examiné les modes Visual Studio. En effet le mode débogage a la même paire mais avec beaucoup d'autres différences dans les structures de code et de débogage. En mode release, il y a un nop avant IsDebuggerPresent que je ne sais pas s'il est lié ou pas. 26 nov.. 172017-11-26 08:32:34

  0

@ de6f mode de libération implique beaucoup d'optimisations du code naïf, il y a pourquoi il y a une différence de longueur. 27 nov.. 172017-11-27 13:25:19

  0

Comprendre cela mais, pourquoi compilateur générant ce code en premier lieu? Un autre avantage pour cela? 27 nov.. 172017-11-27 16:31:26

+1

@ de6f vous avez un statemeny pid = blah compilateur a assigné un var local pid dans la pile ebp-xx et stocké le résultat de blah là alors vous avez un printf le compilateur puis réutilisé le local il ne garde pas à l'esprit le résultat est déjà dans eax il fait comme dit quand en mode débogage compilationn quand vous lui dites pour optimiser il élimine la paire aussi en mode de débogage la paire aide au débogage de niveau source 27 nov.. 172017-11-27 17:58:31

  0

Il semble plus raisonnable si elle ne garde pas cela à l'esprit dans le processus normal de compilation. 27 nov.. 172017-11-27 21:36:58

1

Le code utilise cette forme non optimale afin de correspondre au code d'origine. Il enregistre la valeur dans la variable locale "pid" afin qu'un débogueur puisse la voir. Ensuite, il récupère à nouveau la valeur pour l'utiliser.