2015-02-28 7 views
1

Je suis en train de comprendre le code suivant:assembleur en ligne - PUSHF sans arguments

n = 0; 
asm volatile(
    "pushf\n\t" 
    "pop %%rax\n\t" 
    "or $(1<<8),%%rax\n\t" 
    "push %%rax\n\t" 
    "lea (%%rip),%0\n\t" 
    "popf\n\t" 
    "and $~(1<<8),%%rax\n\t" 
    "push %%rax\n\t" 
    "popf\n\t" 
    : "=g" (start) : : "rax"); 

Je suis en train de le comprendre par le schéma suivant:

asm (assembler template,code. 
    : output operands     (optional) 
    : input operands     (optional) 
    : list of clobbered registers  (optional) 
    ); 

« PUSHF \ n \ t "pousse une valeur à la pile? quelle est la valeur que cette commande pousse à la pile? même pour "popf \ n \ t"

fondamentalement je veux écrire un test qui simule le point d'arrêt d'écriture/lecture de données.

I joint le code du référentiel kvm-unité-test:

int main(int ac, char **av) 
{ 
    unsigned long start; 

    setup_idt(); 
    handle_exception(DB_VECTOR, handle_db); 
    handle_exception(BP_VECTOR, handle_bp); 

sw_bp: 
    asm volatile("int3"); 
    report("#BP", bp_addr[0] == (unsigned long)&&sw_bp + 1); 

    set_dr0(&&hw_bp); 
    set_dr7(0x00000402); 
hw_bp: 
    asm volatile("nop"); 
    report("hw breakpoint", 
      n == 1 && 
      bp_addr[0] == ((unsigned long)&&hw_bp) && dr6[0] == 0xffff0ff1); 

    n = 0; 
    asm volatile(
     "pushf\n\t" 
     "pop %%rax\n\t" 
     "or $(1<<8),%%rax\n\t" 
     "push %%rax\n\t" 
     "lea (%%rip),%0\n\t" 
     "popf\n\t" 
     "and $~(1<<8),%%rax\n\t" 
     "push %%rax\n\t" 
     "popf\n\t" 
     : "=g" (start) : : "rax"); 
    report("single step", 
      n == 3 && 
      bp_addr[0] == start+1+6 && dr6[0] == 0xffff4ff0 && 
      bp_addr[1] == start+1+6+1 && dr6[1] == 0xffff4ff0 && 
      bp_addr[2] == start+1+6+1+1 && dr6[2] == 0xffff4ff0); 

    n = 0; 
    set_dr1((void *)&value); 
    set_dr7(0x00d0040a); 

    asm volatile(
     "mov $42,%%rax\n\t" 
     "mov %%rax,%0\n\t" 
     : "=m" (value) : : "rax"); 
hw_wp: 
    report("hw watchpoint", 
      n == 1 && 
      bp_addr[0] == ((unsigned long)&&hw_wp) && dr6[0] == 0xffff4ff2); 

    return report_summary(); 
} 
+1

Les drapeaux, c'est ce que f signifie. C'est dans votre manuel, n'est-ce pas? – harold

+0

ok, alors comment puis-je savoir ce que la commande pousse aux drapeaux? et quels sont les drapeaux? – KernelingTheCompiler

+1

Il pousse les drapeaux (la plupart du temps de la même manière que n'importe quel autre registre est poussé), pas à eux. "popf" apparaît sur les drapeaux. Tous les drapeaux ne participent pas, les drapeaux VM et RF sont masqués. C'est aussi dans le manuel bien sûr – harold

Répondre

0

Le modèle

asm (assembler template,code. 
    : output operands     (optional) 
    : input operands     (optional) 
    : list of clobbered registers  (optional) 
    ); 

est utilisé pour gcc inline assembly

donc décomposer les parties dans votre premier exemple, il est le code d'assemblage réel qui est exécuté:

"pushf\n\t" 
"pop %%rax\n\t" 
"or $(1<<8),%%rax\n\t" 
"push %%rax\n\t" 
"lea (%%rip),%0\n\t" 
"popf\n\t" 
"and $~(1<<8),%%rax\n\t" 
"push %%rax\n\t" 
"popf\n\t" 

Pour voir exactement ce que chacune de ces instructions fait, vous devriez regarder un manuel d'instructions x86. Cependant, il y a quelques points spécifiques à la syntaxe asm étendue.

Sur la ligne "lea (%%rip),%0\n\t", %0 signifie que ceci sera remplacé par la première valeur de contrainte qui sera listée dans la section output operands. Dans cet exemple, il s'agit de "=g" (start).

Le g signifie "Any register, memory or immediate integer operand is allowed, except for registers that are not general registers." et (start) signifie que la start variable dans le code utilisera cette valeur.

Dans votre exemple, la section des opérandes d'entrée est vide, de sorte que le code asm n'obtient aucune valeur d'entrée du code C précédent. Enfin, dans la liste des registres tabulés, le code indique que rax est clobulé. Cela signifie que le compilateur doit supposer que le code asm peut changer la valeur de rax et que le compilateur devrait enregistrer/restaurer la valeur dans rax avant/après l'exécution du code asm en ligne, si rax était un registre actif.