2017-10-06 2 views
2

J'utilise l'outil PIN Intel pour effectuer une analyse des instructions d'assemblage d'un programme C. J'ai un simple programme C qui imprime "Hello World", que j'ai compilé et généré un exécutable. J'ai la trace d'instructions d'assemblage généré à partir gdb comme this-Suivi des instructions natives dans Intel PIN

Dump of assembler code for function main: 
    0x0000000000400526 <+0>:  push %rbp 
    0x0000000000400527 <+1>:  mov %rsp,%rbp 
=> 0x000000000040052a <+4>:  mov $0x4005c4,%edi 
    0x000000000040052f <+9>:  mov $0x0,%eax 
    0x0000000000400534 <+14>: callq 0x400400 <[email protected]> 
    0x0000000000400539 <+19>: mov $0x0,%eax 
    0x000000000040053e <+24>: pop %rbp 
    0x000000000040053f <+25>: retq 
End of assembler dump. 

J'ai couru un pintool où j'ai donné l'exécutable comme entrée, et je fais une trace d'instruction et d'imprimer le nombre d'instructions. Je souhaite tracer les instructions qui sont de mon programme C et probablement obtenir les opcodes de la machine et faire une sorte d'analyse. J'utilise un outil C++ PIN pour compter le nombre de INSTRUCTIONS-

#include "pin.H" 
#include <iostream> 
#include <stdio.h> 

UINT64 icount = 0; 
using namespace std; 

//==================================================================== 
// Analysis Routines 
//==================================================================== 

void docount(THREADID tid) { 
    icount++; 
} 

//==================================================================== 
// Instrumentation Routines 
//==================================================================== 

VOID Instruction(INS ins, void *v) { 
    INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_THREAD_ID, IARG_END); 
} 

VOID Fini(INT32 code, VOID *v) { 
    printf("count = %ld\n",(long)icount); 
} 

INT32 Usage() { 
    PIN_ERROR("This Pintool failed\n" 
       + KNOB_BASE::StringKnobSummary() + "\n"); 
    return -1; 
} 

int main(int argc, char *argv[]) { 
    if (PIN_Init(argc, argv)) return Usage(); 

    PIN_InitSymbols(); 
    PIN_AddInternalExceptionHandler(ExceptionHandler,NULL); 
    INS_AddInstrumentFunction(Instruction, 0); 
    PIN_AddFiniFunction(Fini, 0); 
    PIN_StartProgram(); 

    return 0; 
} 

Quand je lance mon bonjour programme mondial avec cet outil, je reçois icount = 81563. Je comprends que PIN ajoute ses propres instructions pour l'analyse, mais Je ne comprends pas comment il ajoute autant d'instructions, alors que je n'ai pas plus de 10 instructions dans mon programme C. Il existe également un moyen d'identifier les instructions d'assemblage qui proviennent de mon code et celles générées par le code PIN. Il semble que je ne trouve aucun moyen de faire la différence entre les instructions générées par PIN et celles qui proviennent de mon programme. S'il vous plaît aidez!

+1

Je ne suis pas familier avec le code PIN, mais je suppose qu'il compte aussi les instructions dans la bibliothèque C. – Jester

+0

Essayez de créer un exécutable statique qui effectue un appel système 'exit' directement. (par exemple, retirer la boucle de mon [mov élimination microbenchmark] (https://stackoverflow.com/questions/44169342/can-x86s-mov-really-be-free-why-cant-i-reproduce-this-at- all/44193770 # 44193770)). –

+0

@PeterCordes Quel que soit le contenu de mon programme C, icount est toujours supérieur à 80k. Je ne sais pas s'il existe un moyen de différencier les instructions machine de celles générées par le code PIN. –

Répondre

0

Vous ne mesurez pas ce que vous pensez mesurer. Voir ma réponse ici pour les détails: What instructions 'instCount' Pin tool counts?

Pin fait pas compte ses propres instructions. Le grand nombre est le résultat de la préparation avant et après et l'appel à printf().

+0

I [suggéré] (https://stackoverflow.com/questions/46596570/tracking-native-instructions-in-intel-pin#comment80146865_46596570) l'OP devrait essayer de faire un exécutable statique cela fait juste un appel système 'sys_exit' depuis' _start'. Le PO dit qu'ils ont reçu un «nombre similaire d'instructions», mais votre réponse indique qu'ils l'ont probablement mal fait. –

+0

Je soupçonne certainement que c'est le cas. Je ne l'ai pas fait depuis un moment mais je me souviens que faire un tel exécutable est un peu compliqué. – nitzanms

+1

Pas si vous le faites tout le temps pour microbenchmarking de toute façon: P Voir https://stackoverflow.com/questions/44169342/can-x86s-mov-really-be-free-why-cant-i-reproduce-this-at -all/44193770 # 44193770 (et sortez la boucle, en laissant simplement '_start: xor edi, edi'/'mov eax, 231' /' syscall'.) Voir https://stackoverflow.com/questions/36861903/assembling -32 bits-binaires-sur-un-64-bit-system-gnu-toolchain/36901649 pour savoir comment assembler + lier la source NASM dans un exécutable statique (pas de libc). –