Я читал отличную книгу 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-разрядной? Это очень сбивает с толку! И я нигде не могу найти упоминания об этом. Есть ли кто-нибудь, кто может просветить меня в этой ситуации?