Перейти к содержанию
    

GCC перепутывает регистры на типе float

Пишу на гсс 4.5.2.Кароче заметил что спринтф не правильно схавал флоат, я отдизасмил и сравнил с дизасмом иара

 

char s[56]={0};

sprintf(s, "%f", 55.2);

 

дизасм гсс:

                MOV     R0, SP
                LDR     R1, =unk_4A6
                LDR     R2, =0x404B9999
                LDR     R3, =0x9999999A

 

дизасм иара:

                LDR     R3, =0x404B9999
                LDR     R2, =0x9999999A
                MOV     R0, SP
                ADR     R1, dword_58

 

как видно регистры R2 R3 перепутаны.

 

LDR R2, =0x404B9999

LDR R3, =0x9999999A

 

LDR R3, =0x404B9999

LDR R2, =0x9999999A

 

 

Че делать?

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приведенные фрагменты кода ничего не поясняют и ничего не доказывают потому, что

а) функция sprintf результат выводит в буфер, а не просто в регистры и

б) передача параметров в функцию не описывается стандартом Си, а отдается на откуп конкретной реализации компилятора.

Покажите конечный (якобы неправильный) результат разложения символов (байтов) в буфер(е).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Забыл сказать, функция sprintf является прошивочной и от компилятора не зависит

 

да и не только спринф, многие функции работаеют не так, ибо число другое получается

 

в буфере(gcc): 2D302E303030303030 (-0.000000)

в буфере(iar): 35352E323030303030 (55.20000)

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

б) передача параметров в функцию не описывается стандартом Си, а отдается на откуп конкретной реализации компилятора.
Для ARM существует стандарт на передачу параметров - EABI
да и не только спринф, многие функции работаеют не так, ибо число другое получается
А ваш GCC поддерживает EABI? Возможно у вас старая версия, которая его не поддерживала? Какая версия компилятора, какая сборка? Компилятор какой командой вызывается - arm-elf-gcc / arm-none-eabi-gcc или еще какой?

 

P.S. а на безграмотное первое сообщение с понтами могли бы и не дождаться ответа.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Забыл сказать, функция sprintf является прошивочной и от компилятора не зависит
Это не имеет значения. Корректно написанный код на языке программирования должен давать верный результат при выполнении.

 

да и не только спринф, многие функции работаеют не так, ибо число другое получается

 

в буфере(gcc): 2D302E303030303030 (-0.000000)

в буфере(iar): 35352E323030303030 (55.20000)

Можете привести исходный текст, который при компиляции IAR дает один результат, а при компиляции GCC - другой?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для ARM существует стандарт на передачу параметров - EABIА ваш GCC поддерживает EABI? Возможно у вас старая версия, которая его не поддерживала? Какая версия компилятора, какая сборка? Компилятор какой командой вызывается - arm-elf-gcc / arm-none-eabi-gcc или еще какой?

 

P.S. а на безграмотное первое сообщение с понтами могли бы и не дождаться ответа.

 

И шож там такого безграмотного? Если вы невнимательно читали, то я тут при чем?

Видимо никто не читал первый пост, я ж написал GCC 4.5.2!

компиляю так:

arm-elf-gcc -c -msoft-float -mlittle-endian -mcpu=arm926ej-s -Os -I include -nostdlib -fwide-exec-charset=cp1251 main.c

ну и там линкер ещё..

 

Это не имеет значения. Корректно написанный код на языке программирования должен давать верный результат при выполнении.

 

ага, я догадывался

 

Можете привести исходный текст, который при компиляции IAR дает один результат, а при компиляции GCC - другой?

 

приводил уже, первый пост - невидимка.

 

char s[56]={0};

sprintf(s, "%f", 55.2);

Изменено пользователем vova7890

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

char s[56]={0};

sprintf(s, "%f", 55.2);

 

скорректируйте до полного разжевывания компилятору:

float  a = 55.2;
char s[50];
sprintf(&s[0], "%f", a);

и проверить, что возвращает sprintf.

А какая реализация sprintf поддерживается в вашей библиотеке?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

скорректируйте до полного разжевывания компилятору:

float  a = 55.2;
char s[50];
sprintf(&s[0], "%f", a);

и проверить, что возвращает sprintf.

А какая реализация sprintf поддерживается в вашей библиотеке?

 

гсс разжовывать безтолку, он такой же самый сгенерил код. Оптимизатор то работает :) Реализация спринтфа самая какая ни есть стандартная. Я ж говорю гсс не правильно передал параметры в функцию, поэтому такая лабуда... :crying:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может быть у gcc что-то в инклюдах про spintf прописано?

Попробуйте для контроля обозвать вызываемую функцию по-другому.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

нет, гсс`ые инклуды я поудалял и не использую, у меня все функции в прошивке которые я вызываю по адресу. Так что у меня свои инклуды. От гсс я требую только компиляции, больше ничего

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

компиляю так:

arm-elf-gcc -c -msoft-float -mlittle-endian -mcpu=arm926ej-s -Os -I include -nostdlib -fwide-exec-charset=cp1251 main.c

ну и там линкер ещё..

Товарисч, arm-none-eabi-gcc-4.5.2.exe(т.е. то, чего советовали) это немного не arm-elf-gcc

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Товарисч, arm-none-eabi-gcc-4.5.2.exe(т.е. то, чего советовали) это немного не arm-elf-gcc

 

а вы товарисч предлагает использовать arm-none-eabi-gcc-4.5.2.elf?(линукс) И че как бы гсс не по стандартам еаби собирает? Де скачать на линукс?

 

скачал первое что нашел гсс старый arm-unknown-linux-gnueabi-gcc-4.1.1

 

скомпилял и уррррраааа!!!! Почти :-D

 

Получил на выходе 55.20001, че 1 в конце? :-D

 

дайте ссылку пожалуйста, не могу найти (

 

Нашел arm-none-eabi последней версии, начал компилять, он ругнулся на конструкцию с asm("swi NUMBER"); В чем фишка?

 

static inline long do_SWI0(const int swi_num )
{
    long ret_val;

    asm volatile (
        "swi %1    \n\t" \
        "mov %0, r0 \n\t" \
        :    "=r" (ret_val)
        :    "n" (swi_num)

        :    "r0", "r1", "r2", "r3", "ip", "lr", "memory", "cc"
    );

    return ret_val;
}

 

include/swiadd.h: In function 'do_SWI0':

include/swiadd.h:35:2: warning: asm operand 1 probably doesn't match constraints

include/swiadd.h:35:2: error: impossible constraint in 'asm'

 

 

Изменено пользователем vova7890

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Получил на выходе 55.20001, че 1 в конце? :-D
Почитайте про формат IEE754 и обратите внимание на столбец Decimal digits в строке binary32 и сходите по ссылке binary32.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...