I ' m в настоящее время пытается вызвать общую функцию C из встроенной сборки GCC (плохая идея, я знаю, но мне сегодня скучно ...).
Моя операционная система - Mac OS X, 64 бита, поэтому соглашение о вызовах - System V, то есть аргументы 0-6 передаются через rdi
, rsi
, rdx
, rcx
, r8
и регистры r9
. Другие аргументы помещаются в стек.
Я знаю сигнатуру функции, поэтому могу угадать тип возвращаемого значения и тип аргументов. Регистры r8
и r9
. Другие аргументы помещаются в стек.
Я знаю сигнатуру функции, поэтому могу угадать возвращаемый тип и тип аргументов. Регистры r8
и r9
. Другие аргументы помещаются в стек.
Я знаю сигнатуру функции, поэтому могу угадать возвращаемый тип и тип аргументов. Обладая этой информацией, я могу поместить аргументы в правильные регистры.
Все отлично работает с целочисленными типами, но у меня проблема со значениями с плавающей запятой.
Значения с плавающей запятой необходимо передавать через xmm0
- xmm7
регистры.
Таким образом, основная проблема заключается в следующем. У меня есть переменная C типа float
. Мне нужно переместить эту переменную, скажем, в регистр xmm0
, используя встроенную сборку GCC.
Представьте себе следующий код:
#include <stdio.h>
void foo( int x )
{
printf( "X: %i\n", x );
}
int main( void )
{
int x = 42;
__asm__
(
"mov %[x], %%rdi;"
"call _foo;"
:
: [ x ] "m" ( x )
);
return 0;
}
Вызывается функция foo
с 42 в качестве параметра. Это работает ...
Теперь я пробую то же самое с аргументом float. Мне нужно использовать только movss
вместо mov
, и это работает.
Проблема возникает, когда я пытаюсь вызвать обе функции: Я не трогаю стек, поэтому нет необходимости выполнять очистку ...
Если я вызываю функции непосредственно из C, GCC выдаст следующее:
movl $42, -4(%rbp)
movl $0x42280000, %eax
movl %eax, -8(%rbp)
movl -4(%rbp), %edi
call _foo
movss -8(%rbp), %xmm0
call _bar
Я не понимаю разницы ... Любая помощь будет буду очень признателен :)
Хорошего дня, все
EDIT
Как просили, вот вывод ASM при использовании встроенной сборки:
movl $42, -4(%rbp)
movl $0x42280000, %eax
movl %eax, -8(%rbp)
mov -4(%rbp), %rdi;
call _foo;
movl -8(%rbp), %eax;
movl %eax, -4(%rbp);
movss -4(%rbp), %xmm0;
call _bar;
EDIT2
Как просили, вот вывод GDB:
0x100000e9e <main+4>: movl $0x2a,-0x4(%rbp)
0x100000ea5 <main+11>: mov $0x42280000,%eax
0x100000eaa <main+16>: mov %eax,-0x8(%rbp)
0x100000ead <main+19>: mov -0x4(%rbp),%rdi
0x100000eb1 <main+23>: callq 0x100000e54 <foo>
0x100000eb6 <main+28>: movss -0x8(%rbp),%xmm0
0x100000ebb <main+33>: callq 0x100000e75 <bar>