2016-05-05 2 views
2

Я пытаюсь написать планировщик для запуска так называемых «волокон». К сожалению, я не очень привык писать встроенную сборку.встроенная сборка - бесполезные инструкции промежуточного копирования

typedef struct { 
    //fiber's stack 
    long rsp; 
    long rbp; 

    //next fiber in ready list 
    struct fiber *next; 

} fiber; 

//currently executing fiber 
fiber *fib; 

Так сама первая задача - очевидно - создание волокна для функции main поэтому оно может быть приостановлено.

int main(int argc, char* argv[]){ 

    //create fiber for main function 
    fib = malloc(sizeof(*fib)); 
    __asm__(
     "movq %%rsp, %0;" 
     "movq %%rbp, %1;" 
     : "=r"(fib->rsp),"=r"(fib->rbp) 
     ); 

    //jump to actual main and execute 
    __asm__(...); 

} 

Это компилируется в

movl $24, %edi #, 
    call malloc # 
#APP 
# 27 "scheduler.c" 1 
    movq %rsp, %rcx;movq %rbp, %rdx; # tmp92, tmp93 
# 0 "" 2 
#NO_APP 
    movq %rax, fib(%rip) # tmp91, fib 
    movq %rcx, (%rax) # tmp92, MEM[(struct fiber *)_3].rsp 
    movq %rdx, 8(%rax) # tmp93, MEM[(struct fiber *)_3].rbp 

Почему это компилировать mov сек во временные регистры? Могу ли я как-то избавиться от них?

Первая версия этого вопроса имела выход asm от gcc -O0, с еще большим количеством инструкций и временными данными.

Включение оптимизаций не избавляется от них.

+0

Включили ли вы оптимизацию? – Jester

+0

@Jester У меня не было сначала, но включение их не избавляет от временных (см. Выше). – User1291

+0

C не поддерживает _methods_ – Olaf

ответ

3

превращение их не избавиться от временных

Это было избавиться от некоторых дополнительных нагрузок и магазинов. fib, конечно, все еще присутствует в памяти, так как вы объявили это как глобальную переменную. rax - это возвращаемое значение из malloc, которое должно быть присвоено fib в памяти. Остальные две строки записываются в ваши fib членов, которые также необходимы.

Поскольку вы указали выходы регистра, блок asm не может записываться непосредственно в память. Это легко исправить с ограничением памяти, хотя:

__asm__(
    "movq %%rsp, %0;" 
    "movq %%rbp, %1;" 
    : "=m"(fib->rsp),"=m"(fib->rbp) 
    ); 

Это будет генерировать:

call malloc 
    movq %rax, fib(%rip) 
    movq %rsp, (%rax) 
    movq %rbp, 8(%rax) 
+0

Вы, вероятно, должны использовать '' = rm ", чтобы дать компилятору параметр. В этом случае это не имеет значения, но если вы пишете код, который смотрит на эти значения, компилятор может хранить их в regs inst ead делать магазин-> груз. (Хотя в идеале был бы способ сделать переменную C ссылкой на значение 'rbp' без каких-либо инструкций.) Clang иногда делает неправильный выбор, если заданы ограничения с несколькими опциями, поэтому проверьте код для этого случая. (На самом деле, я не помню подробностей, когда я видел, как clang плохо работает с заявлениями GNU C 'asm', но это может произойти.) –

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