2015-05-19 1 views
1

Я новичок в программировании сборки и, как часть более крупной программы, мне нужно передать значения с плавающей запятой другой C-функции. У меня есть вызов из моей тестовой программы на мою функцию сборки, которая только толкает параметры в правый стек и вызывает вторую функцию C.функция вызова с поплавком в сборке x86 x87

Мой тест C Функция:

extern void ext_func(char *result, double d); // C function 
extern double tester(char *str, float d); 

double a = tester(str, 3.14) 
printf("%s\n", str);  // Resulting in '0.000000' 

// doing some fancy stuff with the float value and puts in result 
ext_func(str, 3.14);  // gives str = "3.140000" 

x86, GCC -m32:

 .globl tester 
tester: 
    pushl %ebp  # Standard 
    movl %esp, %ebp # 
    flds 12(%ebp) # Push second parameter on stack 
    pushl 8(%ebp) 
    call ext_func 
    addl $4, %esp 
    leave 
    ret 

Я думаю, Theres проблема со мной только толкая 32 бит, когда ext_funct ожидая дважды. Но я попытался использовать fldl, fld1, fildl, fldl 12 и 16 (% ebp), а некоторые другие - для «забавы».

  • Мой первый вопрос, являются ext_func отсутствуют некоторые данные в стеке поплавка (ST), и, следовательно, не в состоянии сделать значение с плавающей точкой? (Я понимаю, что вы не имеете функцию вызываемого абонента, но не имеет значение то, что функция делает?)
  • Во-вторых, всегда ли компилятор переходит к f-стеку, чтобы получить значения float, если он их ожидает, или можно прочитать их из памяти?
  • В-третьих, есть ли еще что-то еще здесь? Если я
printf("%f", a);  //3.140000 
printf("%f", str);  //3.140000 

но другой способ a дает большое количество Negativ (100 цифр или так) закончилась по 000000.

ответ

2

32 бит условность использует стек процессора для передачи аргументов с плавающей точкой. Он использует только стек fpu для их возврата. Да, вы должны преобразовать ваш 32-битный float в 64-битный двойной, в соответствии с прототипами, которые вы предоставили.

Обратите внимание, что ext_func является void, что он не возвращает ничего, но вы объявили tester как возвращение double ... это непонятно, что вы хотите, вернулись, я предполагаю, что вы хотите оригинальный d назад (по любой причине) ,

Таким образом, возможная реализация может быть:

 .globl tester 
tester: 
    subl $12, %esp  # allocate space for outgoing arguments 
    movl 16(%esp), %eax # fetch our first argument (str) 
    movl %eax, (%esp) # store as first outgoing argument 
    flds 20(%esp)  # Fetch our second argument as float 
    fstpl 4(%esp)  # store it as second outgoing argument as double 
    call ext_func 
    flds 20(%esp)  # load d as return value 
    addl $12, %esp  # cleanup stack 
    ret 
+0

Это делает много смысла. В моей программе я действительно не хочу иметь float как второй параметр, но неопределенный, например 'tester (char * str, ...)'. Неопределенные числа всегда удваиваются при нажатии на стек? – zill69

+0

Да, аргументы float в переменной части по умолчанию повышаются до удвоения. Конечно, целые числа. – Jester

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

  • Нет связанных вопросов^_^