ex0400_timer_interrupt.ino
int16_t _atoi(const char *s) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wuninitialized"
//sign & c are initialized inside inline asm code
register uint8_t sign, c;
#pragma GCC diagnostic pop
//force result into return registers
register int16_t result asm("r24");
asm (
"ldi %A0, 0x00 \n" //result = 0
"ldi %B0, 0x00 \n"
"1: \n"
"ld %2, Z+ \n" //fetch char
"cpi %2, '-' \n" //negative sign?
"brne 2f \n"
"ldi %3, 0x01 \n" //sign = TRUE
"2: \n"
"cpi %2, '/' + 1 \n" //step over whitespace/garbage
"brcc 3f \n"
"rjmp 1b \n"
"3: \n"
"rjmp 5f \n"
"4: \n"
"ldi r23, 10 \n" //result *= 10
"mul %B0, r23 \n"
"mov %B0, r0 \n"
"mul %A0, r23 \n"
"mov %A0, r0 \n"
"add %B0, r1 \n"
"clr __zero_reg__ \n" //r1 trashed by mul
"add %A0, %2 \n" //result += new digit
"adc %B0, __zero_reg__ \n"
"ld %2, Z+ \n" //fetch next digit char
"5: \n"
"subi %2, '0' \n" //convert char to 0-9
"cpi %2, 10 \n" //end of string?
"brlo 4b \n"
"cpi %3, 0 \n" //negative?
"breq 6f \n"
"com %B0 \n" //negate result
"neg %A0 \n"
"sbci %B0, -1 \n"
"6: \n"
: "+r" (result) : "z" (s), "a" (c), "a" (sign) : "memory"
);
return result;
}
ex0401_timer_interrupt.ino
Plan du Site :
Home
Microcontroleur
avr_assembler.html
( = http://www.juggling.ch/gisin/microcontroleur/avr_assembler.html )
Page mise à jour le 4 avril 2018 par Bernard Gisin
( Envoyer un e-mail )
Hébergement par : www.infomaniak.ch