Соглашение о вызовах ассемблера 32-битное против 64-битного

Я читал отличную книгу Programming Ground Up, желая изучить ассемблер. Я хотел вызвать свою функцию сборки из C. на 32-битной машине, хотя это и не описано в книге.

Здесь я сохраняю первый аргумент в ]% ebx и второй в % ecx .

.type power, @function
.globl power
power:
    pushq   %ebp
    movl    %esp, %ebp
    subl    $4, %esp

    movl    8(%ebp), %ebx
    movl    12(%ebp), %ecx

Я компилирую это (и остальную функцию) в объектный файл, создаю main.c, где я прототипирую функцию и назовите это примерно так:

int power(int b, int x);
int a = power(2, 1);

Однако, когда я компилирую это на 64-битной машине, я получаю очень неожиданные результаты. Я изменил очевидное, например, тот факт, что % esp и % epb необходимо заменить на % rsp и % rpb , но копание с помощью GDB показывает, что аргументов нигде нет в стеке!

Проверяя, что происходит, используя параметр -S в GCC, я вижу, что вместо того, чтобы помещать переменные в стек , GCC сохраняет аргументы в регистрах.

 movl $1, %esi
 movl $2, %edi
 call power

На 32-битной машине он делает то, что я ожидал, и помещает аргументы в стек:

 movl $1, 4(%esp)
 movl $2, (%esp)
 call power

Что же здесь происходит? Почему GCC передает аргументы в регистры на 64-разрядной версии и в стеке на 32-разрядной? Это очень сбивает с толку! И я нигде не могу найти упоминания об этом. Есть ли кто-нибудь, кто может просветить меня в этой ситуации?

10
задан nrz 16 January 2013 в 07:37
поделиться