asm, сгенерированный GCC :: Где я присвоил этот регистр?

Возможный дубликат:
Не уверен, почему мы добавляем регистры %rdx и %rax, когда ассемблерный код использует %eax и %edx

все. Итак, вот моя минимальная программа:

int main(int argc, char * argv[]){
    volatile int a;
    volatile int b;
    volatile int c;
    a = 9;
    b = 15;
    c = a+b;
    return c;
}

Теперь я запускаю для этого gcc -S, и вот суть сгенерированной сборки:

.LCFI1:
    movl    %edi, -20(%rbp)    //unknown setup
    movq    %rsi, -32(%rbp)    //unknown setup
    movl    $9, -4(%rbp)       //a=9, so -4(%rbp) is the register for a.
    movl    $15, -8(%rbp)      //b=15, so -8(%rbp) is b's register.
    movl    -4(%rbp), %edx     //move a into the register for addition.
    movl    -8(%rbp), %eax     //move b into the register for additon.
    leal    (%rdx,%rax), %eax  //Add a and b, store in %eax. (PROBLEM LINE)
    movl    %eax, -12(%rbp)    //Store %eax in c's register.
    movl    -12(%rbp), %eax    //get ready to return c. 
    leave                      //we're done here.
    ret

Итак, вы видите строку, которую я указываю как проблемную. Вот мой вопрос: что такое %rdx и %rax? Единственные регистры, в которые я загружал данные, это %edx и %eax.

Так как программа работает, %rdx и %rax должны быть своего рода псевдонимом для %edx и %eax соответственно. Может ли кто-нибудь объяснить нюансы номенклатуры регистров x86? Я полностью в темноте по этому поводу.

(Обратите внимание, если я изменю строку проблемы на addl %edx, %eax, результат будет таким же, но если я изменю ее на addl %rdx, %rax, я получу «Ошибка: неправильный регистр«% rax»используется с суффиксом l")


person mmtrebuchet    schedule 18.12.2012    source источник
comment
это x86_64, а не x86. Для 64-битной инструкции требуется суффикс q, а не l, поэтому вы получаете ошибку   -  person phuclv    schedule 03.10.2013


Ответы (1)


Посмотрите здесь если вы не уверены в регистрах и их размерах. Подумайте об этом так

union{
  struct{
    uint32_t eax;
    uint32_t padd;
  };
  uint64_t rax;
};

eax и rax используют один и тот же регистр, eax является младшей частью этого регистра.

По этой причине addl не будет работать с регистрами с префиксом r, они длиннее, чем ожидает addl. Вместо этого попробуйте addq.

person Max    schedule 18.12.2012