Пт окт 22, 2021 10:47:07
char* nex_char(uint32_t value, char* tail_txt)
{
int32_t tmp, jump; jump = 0;
volatile char* tex; tex = tail_txt;
*(tex--) = 0;
do
{
tmp = value & 0x0F;
if (tmp > 9 ) *(tex--) = tmp + 55;
else *(tex--) = tmp + '0';
value >>= 4; jump++;
}while ((value )||(jump & 1));
*(tex--) = 'x';
*tex = '0';
return tex;
};
Пт окт 22, 2021 11:54:33
char* nex_char(uint32_t value, char* tail_txt)
{
int32_t jump = 0;
*tail_txt-- = 0;
do
{
int32_t tmp = value & 0x0F;
if (tmp > 9) tmp += 7;
*tail_txt-- = tmp + '0';
value >>= 4;
jump++;
} while (value || (jump & 1));
*(volatile char*)tail_txt-- = 'x'; // volatile, если сильно хочется
*(volatile char*)tail_txt = '0';
return tail_txt;
}
Пт окт 22, 2021 12:18:22
//Преобразует число x в строку в str с основанием 10.
//Возвращает указатель на завершающий 0-ой символ.
char * utoa10(u32 x, char *str)
{
#define D ((B35 + 5) / 10)
u32 i;
char *s1, *s = str;
do {
x = (i = x) * D >> 35;
*s++ = i - x * 10 + '0';
} while (x);
*(s1 = s) = 0;
while ((uint)--s > (uint)str) {
i = *s;
*s = *str;
*str++ = i;
}
return s1;
#undef D
}
char * utoa10(u32 x, char *str)
{
_Z6utoa10mPc: (+1)
0xB470 PUSH {R4-R6}
0x460C MOV R4,R1
#define D ((B35 + 5) / 10)
u32 i;
char *s1, *s = str;
REQUIRE ?Subroutine0
;; // Fall through to label ?Subroutine0
?Subroutine0: (+1)
0x4625 MOV R5,R4
0x.... 0x.... LDR.W R6,??DataTable4 ;; 0xcccccccd
??Subroutine0_0: (+1)
0x4602 MOV R2,R0
0xFBA6 0x0102 UMULL R0,R1,R6,R2
0x08C8 LSRS R0,R1,#+3
0xEB00 0x0380 ADD R3,R0,R0, LSL #+2
0xEBA2 0x0143 SUB R1,R2,R3, LSL #+1
0x3130 ADDS R1,R1,#+48
0x2800 CMP R0,#+0
0xF805 0x1B01 STRB R1,[R5], #+1
0xD1F2 BNE.N ??Subroutine0_0
0x4628 MOV R0,R5
0x2100 MOVS R1,#+0
0x7001 STRB R1,[R0, #+0]
0xE004 B.N ??Subroutine0_1
??Subroutine0_2: (+1)
0x7829 LDRB R1,[R5, #+0]
0x7822 LDRB R2,[R4, #+0]
0x702A STRB R2,[R5, #+0]
0xF804 0x1B01 STRB R1,[R4], #+1
??Subroutine0_1: (+1)
0x1E6D SUBS R5,R5,#+1
0x42AC CMP R4,R5
0xD3F7 BCC.N ??Subroutine0_2
0xBC70 POP {R4-R6}
0x4770 BX LR ;; return
Пт окт 22, 2021 12:20:31
Пт окт 22, 2021 12:20:57
Пт окт 22, 2021 12:22:31
Пт окт 22, 2021 12:24:01
Пт окт 22, 2021 12:46:32
#define B0 0x00000001ul
...
#define B31 0x80000000ul
#define B32 (1ull << 32)
#define B33 (1ull << 33)
#define B34 (1ull << 34)
#define B35 (1ull << 35)
...
typedef __packed u16 u16p8;
typedef __packed s16 s16p8;
typedef __packed u32 u32p8;
typedef __packed s32 s32p8;
typedef __packed u64 u64p8;
typedef __packed s64 s64p8;
typedef __packed u32 u32p16;
typedef __packed s32 s32p16;
typedef __packed u64 u64p16;
typedef __packed s64 s64p16;
typedef __packed u64 u64p32;
typedef __packed s64 s64p32;
u16p8 *ptr = ...;
*ptr = ...;
Пт окт 22, 2021 14:10:42
AVI-crak писал(а):И наверно все-таки hex_char?
#define D ((B35 + 5) / 10)
Пт окт 22, 2021 14:30:33
#define D ((B35 + 5) / 10)
Пт окт 22, 2021 14:35:16
#define D ((B35 + 5) / 10)
Пт окт 22, 2021 16:17:35
uint32_t divu10(uint32_t val) { return val * (((1ULL << 35) + 5) / 10) >> 35; }
uint32_t divu100(uint32_t val) { return val * (((1ULL << 38) + 5) / 100 + 1) >> 38; }
uint32_t divu1000(uint32_t val) { return val * (((1ULL << 41) + 5) / 1000 + 1) >> 41; }
uint32_t divu1M(uint32_t val) { return val * (((1ULL << 51) + 5) / 1000000 + 1) >> 51; }
uint32_t remu10(uint32_t val) { return val - divu10(val) * 10; }
Пт окт 22, 2021 17:41:47
#include <avr/io.h>
#define B35 (1ULL<<35)
char * utoa10(uint32_t x, char *str){
#define D ((B35 + 5) / 10)
uint32_t i;
char *s1, *s = str;
do {
x = (i = x) * D >> 35;
*s++ = i - x * 10 + '0';
} while (x);
*(s1 = s) = 0;
while ((unsigned int)--s > (unsigned int)str) {
i = *s;
*s = *str;
*str++ = i;
}
return s1;
#undef D
}
int main(){
char buf[20];
volatile char *res;
res = utoa10(0x12345678, buf);
}
$ avr-gcc main.c -mmcu=atmega8 -Os
$ avr-size a.out
text data bss dec hex filename
432 0 0 432 1b0 a.out
#include <avr/io.h>
char* u32toa(uint32_t val, char *buf){
buf+=10;
buf[1] = 0;
do{
buf[0] = val % 10;
val /= 10;
if(buf[0] < 10)buf[0] += '0'; else buf[0] = buf[0] - 0x0A + 'A';
buf--;
}while(val);
return buf;
}
int main(){
char buf[20];
volatile char *res;
res = u32toa(0x87654321, buf);
}
$ avr-gcc main.c -mmcu=atmega8 -Os
$ avr-size a.out
text data bss dec hex filename
264 0 0 264 108 a.out
Пт окт 22, 2021 18:15:28
PUSH {R4}
LDR.W R12,=0CCCCCCCDh
MOVS R4,#10
ppp_02: UMULL R2,R3,R12,R0
LSRS R3,R3,#+3
MLS R2,R3,R4,R0
ADDS R2,#'0'
MOVS R0,R3
STRB R2,[R1], #+1
BNE.N ppp_02
STRB R0,[R1]
POP {R4}
BX LR
Пт окт 22, 2021 18:24:48
Пт окт 22, 2021 18:52:45
Пт окт 22, 2021 19:22:16
При том, что именно эта ветка дискуссии была про AVR, естественно. Ну и потому что я синтаксис ассемблера AVR знаю гораздо лучше.Не понял - а при чём тут AVR если тема про ARM?
Я ведь выложил дизасм листинг: это целая подпрограмма __lshrdi3Это одна команда длительностью = 1такт.
Такое высказывания требует подтверждения числами.Как ни сравнивайте, а на любом CPU, который умеет аппаратное умножение, но не умеет деление (или деление намного дольше выполняется), вариант с умножением будет значительно быстрее.
Пт окт 22, 2021 21:59:05
Пт окт 22, 2021 23:34:57
Числами будет трудно, дешевле использовать логику.
Умножение очень хорошо выполняется одновременными каскадными сложениями. В первый цикл складываются сразу 16 пар, во второй 8, потом есно 4, и последние 2 числа.
Пт окт 22, 2021 23:58:09