2015-02-28 4 views
1

Я пытаюсь понять следующий код:Встроенный ассемблер - PUSHF без аргументов

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"); 

Я пытаюсь понять это по следующей схеме:

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

«PUSHF \ п \ t "толкает значение в стек? каково значение, которое эта команда подталкивает к стеку? same for "popf \ n \ t"

В основном я хочу написать тест, который имитирует точку останова записи/чтения данных.

Я приложил код из квм-модульного тестирования хранилища:

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

Флаги, это то, что означает f. Это в вашем руководстве, не так ли? – harold

+0

ОК, так как я могу знать, что команда нажимает на флаги? и какие флаги это? – KernelingTheCompiler

+1

Он подталкивает флаги (в основном так же, как и любой другой регистр), а не им. 'popf' появляется на флажках. Не все флаги участвуют, флаги VM и RF маскируются. Это также в руководстве, конечно – harold

ответ

0

Узор

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

используется для gcc inline assembly

Так ломают части в вашем примере сначала является фактическим кодом сборки, который выполняется:

"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" 

Чтобы узнать, что именно делает каждая из этих инструкций, вы должны ознакомиться с инструкцией по эксплуатации x86. Тем не менее, существует несколько точек, характерных для расширенного синтаксиса asm.

В строке "lea (%%rip),%0\n\t"%0 означает, что это будет заменено первым значением ограничения, которое будет указано в разделе output operands. В этом примере это "=g" (start).

g означает "Any register, memory or immediate integer operand is allowed, except for registers that are not general registers." и (start) означает, что в коде переменная start будет использовать это значение.

В вашем примере раздел операндов ввода пуст, поэтому код asm не получает никаких входных значений из более раннего кода C.

Наконец, в списке разделенных регистров регистров код указывает, что rax сбито. Это означает, что компилятор должен предположить, что код asm может изменить значение rax, и поэтому компилятору необходимо будет сохранить/восстановить значение в rax до/после выполнения кода inline asm, если rax был активным регистром.

Смежные вопросы