1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
/*
itoa.S
Copyright (C) 2000 Michael Rickmann <mrickma@gwdg.de>
Changes: Reiner Patommel <rpato@post4.tele.dk>
(no stack space used anymore)
Permission to use, copy, modify, and distribute this software and
its documentation for any purpose and without fee is hereby granted,
without any conditions or restrictions. This software is provided
"as is" without express or implied warranty.
#include <stdlib.h>
char *itoa(int value, char *string, int radix);
----------------------------------------------------------------------
*/
#include "macros.inc"
#include "ctoasm.inc"
.global _U(itoa)
.func _U(itoa)
/* arguments */
#define r_val_hi r25
#define r_val_lo r24
#define r_str_hi r23
#define r_str_lo r22
#define r_radix r20
/* local variables */
#define r_lstr_hi r19
#define r_lstr_lo r18
_U(itoa):
mov ZL, r_str_lo ; *string
mov ZH, r_str_hi
mov r_lstr_lo, ZL ; save &string
mov r_lstr_hi, ZH
cpi r_radix, 2 ; no radix < 2
brlt terminate
cpi r_radix, 10 ; decimal number ?
brne divide_loop
bst r_val_hi, 7 ; remember sign of value
tst r_val_hi ; sign of value ?
brge divide_loop
com r_val_hi ; make positive
neg r_val_lo
sbci r_val_hi, 0xff
divide_loop:
mov r22, r_radix ; radix
clr r23 ; dividend in r25:r24, divisor in r23:r22
XCALL _U(__udivmodhi4); quotient in r23:r22, remainder in r25:r24
; clobbered: r0, r21, r26, r27
; call-used but preserved: r18, r19, r20, r30, r31
subi r24, 0xd0 ; + '0'
cpi r24, 0x3a ; > '9' ?
brlt L_10
subi r24, 0xd9 ; + 'a' - 10 - '0'
L_10:
st Z+, r24 ; write char to string in reverse order
mov r_val_lo, r22 ; quotient -> dividend
mov r_val_hi, r23
sbiw r_val_lo, 0 ; value == 0 ?
brne divide_loop
clr r21
bld r21, 0 ; get sign again
tst r21 ; negative number?
breq n_terminate ; no, positive
ldi r21, '-'
st Z+, r21 ; write minus sign to string
n_terminate: ; restore &string as return value
mov r_val_hi, r_lstr_hi
mov r_val_lo, r_lstr_lo
terminate:
st Z, __zero_reg__ ; terminate string
XJMP _U(strrev) ; reverse string
.endfunc
|