реклама на сайте
подробности

 
 
8 страниц V  « < 4 5 6 7 8 >  
Reply to this topicStart new topic
> Вопрос С
ViKo
сообщение Jun 29 2010, 19:52
Сообщение #76


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(zltigo @ Jun 29 2010, 21:38) *
Вот как написано, так пробуйте.

Во всех (!) перечисленнных вариантах делается одно и то же: +8 +2
Код
;;;34       *(uint32_t *)(string += sizeof(int32_t)) =  '    ';  
000006  600a              STR      r2,[r1,#0]
;;;35       *(uint32_t *)(string += sizeof(int32_t)) = (uint32_t )"  0";
000008  604a              STR      r2,[r1,#4]
00000a  a23b              ADR      r2,|L1.248|
00000c  f8412f08          STR      r2,[r1,#8]!
;;;36       string += 2;
000010  1c89              ADDS     r1,r1,#2
;;;37
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 29 2010, 21:13
Сообщение #77


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (ViKo @ Jun 29 2010, 22:52) *
Во всех (!) перечисленнных вариантах делается одно и то же: +8 +2
CODE
;;;34       *(uint32_t *)(string += sizeof(int32_t)) =  '    ';  
000006  600a              STR      r2,[r1,#0]
;;;35       *(uint32_t *)(string += sizeof(int32_t)) = (uint32_t )"  0";
000008  604a              STR      r2,[r1,#4]
00000a  a23b              ADR      r2,|L1.248|
00000c  f8412f08          STR      r2,[r1,#8]!
;;;36       string += 2;
000010  1c89              ADDS     r1,r1,#2
;;;37

Выложите-ка просто целиком и без редактирования ДВА листинга, как у Вас было и как я предложил. Тогда будет видно.
Пока "идеальный варинат" этого кусочка мог-бы быть такой:
CODE
STR      r2,[r1,#0]
STR      r2,[r1,#4]
ADR      r2,......
STR      r2,[r1,#8]
ADDS     r1,r1,#10

Все команды по 16бит и на два байта меньше относительно приведенного выше варианта.
Но компилятору чего-то у уму заклинило sad.gif
А что будет если так:
CODE
*(uint32_t *)(string + 4) =  '    ';  
  *(uint32_t *)(string + 8 ) = (uint32_t )"  0";
  string += 10;



P.S.
Компильнул IAR-овским компилятором (слега еще подправив,но в общем, как в 73 посте) все, как задумывалось получилось и 54 байта размер кода.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 30 2010, 08:00
Сообщение #78


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Выкладываю ваш вариант.
Последнее, что вы написали, тоже делал.
Пара вопросов, возникших в процессе... -
1. Можно ли "заинлайнить" библиотечную функцию, ту же div, например?
2. Есть ли способ задать массив, выровненный по 4-байтовой границе?

upd.
Вах, получилось!
Код
void  itoad(int number, uint8_t *string)
{
  #define  FOUR_SPACES  ' ' | ' ' << 8 | ' ' << 16 | ' ' << 24
  uint8_t  sign;
  
  *(uint32_t *)(string) = FOUR_SPACES;
  *(uint32_t *)(string + 4) = FOUR_SPACES;    
  *(uint32_t *)(string + 8) = (uint32_t)"  0";
  string += 10;
//  *(uint32_t *)(string += sizeof(int32_t)) =  '    ';  
//  *(uint32_t *)(string += sizeof(int32_t)) = (uint32_t )"  0";
//  string += 2;
      
  if (!number) return;
  if (number > 0) sign = '+';
  else {
    number = -number;
    sign = '-';
  }
  do {
    *string-- = number % 10 + '0';
  } while (number /= 10);
  *string = sign;
}

58 байтов
Код
;;;31       *(uint32_t *)(string) = FOUR_SPACES;
000002  f04f3220          MOV      r2,#0x20202020
;;;32       *(uint32_t *)(string + 4) = FOUR_SPACES;    
000006  600a              STR      r2,[r1,#0]
;;;33       *(uint32_t *)(string + 8) = (uint32_t)"  0";
000008  604a              STR      r2,[r1,#4]
00000a  a23a              ADR      r2,|L1.244|
;;;34       string += 10;
00000c  608a              STR      r2,[r1,#8]
00000e  310a              ADDS     r1,r1,#0xa

Вроде уже делал так.
Прикрепленные файлы
Прикрепленный файл  keil_temp.txt ( 8.62 килобайт ) Кол-во скачиваний: 82
 
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 30 2010, 09:22
Сообщение #79


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



"Шеф, все пропало!..."
По команде *(uint32_t *)(string + 8) = (uint32_t)" 0";
заносится адрес строки, а не сама строка!

На всякий случай, если кто-то заинтересуется, выдаю работающий код.
Код
void  itoad(int number, uint8_t *string)
{
  #define  TETRASPACE  ' ' | ' ' << 8 | ' ' << 16 | ' ' << 24
  #define  TETRATAIL   ' ' | ' ' << 8 | '0' << 16 | '\0'<< 24
  uint8_t  sign;
  *(uint32_t *)(string) = TETRASPACE;
  *(uint32_t *)(string + 4) = TETRASPACE;    
  *(uint32_t *)(string + 8) = TETRATAIL;
  string += 10;
  if (!number) return;
  if (number > 0) sign = '+';
  else {
    number = -number;
    sign = '-';
  }
  do {
    *string-- = number % 10 + '0';
  } while (number /= 10);
  *string = sign;
}


Часть листинга, обратите внимание, стоит команда LDR, а не ADR, как раньше
Код
;;;31       *(uint32_t *)(string) = TETRASPACE;
000002  f04f3220          MOV      r2,#0x20202020
;;;32       *(uint32_t *)(string + 4) = TETRASPACE;    
000006  600a              STR      r2,[r1,#0]
;;;33       *(uint32_t *)(string + 8) = TETRATAIL;
000008  604a              STR      r2,[r1,#4]
00000a  4a3a              LDR      r2,|L1.244|
;;;34       string += 10;
00000c  608a              STR      r2,[r1,#8]
00000e  310a              ADDS     r1,r1,#0xa
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 30 2010, 11:26
Сообщение #80


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



16-битовая версия (на основе 32-битовой)
Код
void  i16toad(int16_t number, uint8_t *string)
{
  #define  TETRASPACE  ' ' | ' ' << 8 | ' ' << 16 | ' ' << 24
  #define  TETRATAIL   ' ' | '0' << 8 | '\0'<< 16 | '\0'<< 24
  uint8_t sign;
  int32_t num = (int32_t)number;
  *(uint32_t *)string = TETRASPACE;
  *(uint32_t *)(string + 4) = TETRATAIL;
  string += 5;
  if (!num) return;
  else
    if (num > 0) sign = '+';
    else {
      sign = '-';
      num = -num;
    }
  do {
    *string-- = num % 10 + '0';
  } while (num /= 10);
  *string = sign;  
}

Те же 58 байтов, но нет константы 4-байтовой. 105 тактов для -32767.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jun 30 2010, 11:31
Сообщение #81


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Вот никак не могу понять, почему никто до сих пор не придумал оператор, который возвращает сразу и частное, и остаток.
Ведь они оба образуются при операции деления.
Зачем 2 раза проводить одну и ту же операцию, чтобы взять по очереди две половинки результата?
laughing.gif
Тяжёлое наследие бейсика...


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 30 2010, 11:35
Сообщение #82


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(MrYuran @ Jun 30 2010, 14:31) *
Вот никак не могу понять, почему никто до сих пор не придумал оператор, который возвращает сразу и частное, и остаток.

В 51-й микроЭВМ была. А в Cortex заменяется двумя командами (upd. Вернее, тремя. Исправил код). Дважды не делается.
Код
000022  4602              MOV      r2,r0
000024  fb90f0f3          SDIV     r0,r0,r3
000028  fb032210          MLS      r2,r3,r0,r2
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 30 2010, 13:12
Сообщение #83


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Напоследок - проверил вариант с преобразованием в 4.28, для int16, с той же формой выдачи результата. Получилось 100 байтов, 150 циклов, не лучший способ. В-общем, вариант itoa для Cortex для себя я уже выбрал smile.gif.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 30 2010, 13:34
Сообщение #84


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(ViKo @ Jun 30 2010, 17:12) *
Получилось 100 байтов, 150 циклов, не лучший способ.

Ну, этот способ я выбирал с учетом специфики ARM7 - там картина должна быть противоположной.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 30 2010, 13:44
Сообщение #85


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(aaarrr @ Jun 30 2010, 15:34) *
Ну, этот способ я выбирал с учетом специфики ARM7 - там картина должна быть противоположной.

Я понял.
Сложнее поставить знак в нужное место, и для гашения лидирующих нулей нужна переменная. Зато вместо деления - умножение. В-общем, все наоборот.
Идея интересная - поделить число на 10000 и умножить на 2^28 (для других размерностей можно использовать другие числа, например, для 8-битов - использовать форму 4.12, умножив на 41).
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 30 2010, 19:02
Сообщение #86


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (ViKo @ Jun 30 2010, 11:22) *
На всякий случай..

Ну если упорно не хотите нормальное сравнение следать, то вот:
CODE
     59          void  itoad(int number, uint8_t *string)
     60          {
   \                     itoad:
   \   00000000   10B4               PUSH     {R4}
     61            int  sign;
     62            *(int32_t *) string =        0x20202020;
   \   00000002   ....               LDR.N    R2,??DataTable1_1;; 0x20202020
   \   00000004   0A60               STR      R2,[R1, #+0]
     63            *(int32_t *)(string += 4) =  0x20202020;  
   \   00000006   4A60               STR      R2,[R1, #+4]
     64            *(int32_t *)(string += 4) =  0x00302020;
   \   00000008   ....               LDR.N    R2,??DataTable1_2;; 0x302020
   \   0000000A   8A60               STR      R2,[R1, #+8]
     65            string += 2;
   \   0000000C   0A31               ADDS     R1,R1,#+10
     66            if (!number) return;
   \   0000000E   78B1               CBZ.N    R0,??itoad_0
     67            if (number > 0) sign = '+';
   \   00000010   0128               CMP      R0,#+1
   \   00000012   AEBF               ITEE     GE
   \   00000014   2B22               MOVGE    R2,#+43
   \   00000016   4042               RSBLT    R0,R0,#+0
   \   00000018   2D22               MOVLT    R2,#+45
     68            else {
     69              number = -number;
     70              sign = '-';
     71            }
     72            do {
     73              *string-- = number % 10 + '0';
   \                     ??itoad_1:
   \   0000001A   0A23               MOVS     R3,#+10
   \   0000001C   90FBF3F4           SDIV     R4,R0,R3
   \   00000020   03FB1400           MLS      R0,R3,R4,R0
   \   00000024   3030               ADDS     R0,R0,#+48
   \   00000026   01F80109           STRB     R0,[R1], #-1
     74            } while (number /= 10);
   \   0000002A   2000               MOVS     R0,R4
   \   0000002C   F5D1               BNE.N    ??itoad_1
     75            *string = sign;
   \   0000002E   0A70               STRB     R2,[R1, #+0]
     76          }
   \                     ??itoad_0:
   \   00000030   10BC               POP      {R4}
   \   00000032   7047               BX       LR             ;; return


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jun 30 2010, 20:29
Сообщение #87


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(zltigo @ Jun 30 2010, 22:02) *
Ну если упорно не хотите нормальное сравнение сделать, то вот:

Вы имеете в виду сравнение кода, или операции сравнения внутри кода? Почему не хочу? Еще как! Листинг я же выдал, там, в файлике keil_temp.txt (он и создается Keil-ом именно в таком виде, с расширением txt). Вот еще раз, после замены типа переменной sign (думал, может в ней дело). С недоумением разглядываю ваш и свой листинги, ничего путного на ум не приходит.
Код
                  itoad PROC
;;;27      ***************************************************************************
****/
;;;28     void  itoad(int number, uint8_t *string)
000000  b510              PUSH     {r4,lr}
;;;29     {
;;;30       #define  TETRASPACE  ' ' | ' ' << 8 | ' ' << 16 | ' ' << 24
;;;31       #define  TETRATAIL   ' ' | ' ' << 8 | '0' << 16 | '\0'<< 24
;;;32     //  uint8_t  sign;
;;;33       int  sign;
;;;34       *(uint32_t *)(string) = TETRASPACE;
000002  f04f3220          MOV      r2,#0x20202020
;;;35       *(uint32_t *)(string + 4) = TETRASPACE;    
000006  600a              STR      r2,[r1,#0]
;;;36       *(uint32_t *)(string + 8) = TETRATAIL;
000008  604a              STR      r2,[r1,#4]
00000a  4a62              LDR      r2,|L1.404|
;;;37       string += 10;
00000c  608a              STR      r2,[r1,#8]
00000e  310a              ADDS     r1,r1,#0xa
;;;38       if (!number) return;
000010  2800              CMP      r0,#0
000012  d011              BEQ      |L1.56|
;;;39       if (number > 0) sign = '+';
000014  dd02              BLE      |L1.28|
000016  f04f042b          MOV      r4,#0x2b
00001a  e001              B        |L1.32|
                  |L1.28|
;;;40       else {
;;;41         number = -number;
00001c  4240              RSBS     r0,r0,#0
;;;42         sign = '-';
00001e  242d              MOVS     r4,#0x2d
                  |L1.32|
;;;43       }
;;;44       do {
;;;45         *string-- = number % 10 + '0';
000020  230a              MOVS     r3,#0xa
                  |L1.34|
000022  4602              MOV      r2,r0
000024  fb90f0f3          SDIV     r0,r0,r3
000028  fb032210          MLS      r2,r3,r0,r2
00002c  3230              ADDS     r2,r2,#0x30
00002e  f8012901          STRB     r2,[r1],#-1
;;;46       } while (number /= 10);
000032  2800              CMP      r0,#0
000034  d1f5              BNE      |L1.34|
;;;47       *string = sign;
000036  700c              STRB     r4,[r1,#0]
                  |L1.56|
;;;48     }
000038  bd10              POP      {r4,pc}
;;;49    
                          ENDP

У вас метка itoad играет какую-то роль? Почему-то у меня запоминается в стеке LR, а у вас нет.
У вас в строке 63 должно быть число 0x20202020 или, как написано?
Сравнение number производится по-разному, но я не вижу в исходниках разницы.
И это LDR.N - там действительно будет по 2 байта? Где-то рядом таблица?
Забавно, что байты в машинных кодах в IAR и Keil написаны по-разному. Где младший, где старший?
Еще один прикол - у меня '+' заносится в регистр 4-байтовой командой (потому что не имеет повторяющейся последовательности?), а '-' 2-байтовой. У вас все 2-байтовые.

Неужели IAR настолько лучше Keil?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 30 2010, 21:14
Сообщение #88


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (ViKo @ Jun 30 2010, 22:29) *
У вас в строке 63 должно быть число 0x20202020 или, как написано?

Следы экспериментов. Все 20
QUOTE
У вас метка itoad играет какую-то роль?

Не у меня, а у ASM - точка входа в эту подпрограмму.
QUOTE
Где-то рядом таблица?

А зачем ей быть далеко? IAR Компилятор сделал все корректно и на 6 байт короче.
QUOTE
Почему-то у меня запоминается в стеке LR

Keil решил сэкономить на BX LR





--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jun 30 2010, 21:42
Сообщение #89


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(MrYuran @ Jun 30 2010, 14:31) *
Тяжёлое наследие бейсика...

Это просто обязано быть отдано на откуп оптимизатору, иначе ломается синтаксис арифметического выражения. Тернарные операции с двумя значениями - это невозможно использовать.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 1 2010, 08:55
Сообщение #90


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(Сергей Борщ @ Jun 29 2010, 17:18) *
Знатная грабля. Исключение при первой же string, начало которой не попадает на границу 4 байт. Или просто порушенные соседние данные.

Грабли можно избежать, если определить строку в виде объединения байтов и 4-байтовых слов.
2 all:
Как сделать в Keil то же, что и в IAR?

Цитата(zltigo @ Jul 1 2010, 00:14) *
IAR Компилятор сделал все корректно и на 6 байт короче.

Только в таблице у него 8 байтов, а у Keil-а 4. Итого, с учетом таблицы, 60 байтов против 62 байтов.

P.S. А тема-то, действительно, начинает соответствовать своему названию - "Вопрос C" smile.gif
Go to the top of the page
 
+Quote Post

8 страниц V  « < 4 5 6 7 8 >
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 00:01
Рейтинг@Mail.ru


Страница сгенерированна за 0.01566 секунд с 7
ELECTRONIX ©2004-2016