converting string to int assembly

Discussion in 'Embedded Systems and Microcontrollers' started by snr, Mar 14, 2016.

  1. snr

    Thread Starter New Member

    Mar 14, 2016
    I have been trying to write the code on HCS12 for hours . My algorithm is that read the string char-by-char, subtract #$30, which means '0' and hold it in a address. Hold another random address in which is filled by 0. Then until end of the string, multiply by 10 content of the random address and add content of the address which is used to convert int by subtracting #$30. I'm really exhausted and hard to implement my algorithm. By the way, I don't know whether it is possible but, I think I can't use default multiplier EMUL, because it uses and writes onto Y and D registers.

    Some pseudos:
    Code (ASM):
    2. num = num*10 + conv(next digit).
    3. var * 10:
    4. res = var
    5. res << 1 (shift left)
    6. res << 1
    7. res = res + var
    8. res << 1
    10. Now res equals var*10
    My stucked code:
    Code (Microchip Assembler):
    2. MYSTR FCC "1337"
    3. Entry:
    5. LDX #MYSTR
    6. CLRA
    7. STAA $1900 ; random address
    8. loop:
    9. LDAA 1, x+ ; pointer to string
    10. CMPA #0 ; check end of string
    11. BEQ halt ; if end of string end the program
    12. BRA atoi ; num in accumulator A is converted to int
    13. ;BRA halt
    15. atoi:
    16. STAA $1300
    17. LDAB $1300
    18. SUBB #$30
    19. ;----- number - '0' converts to int
    20. JSR mult
    21. BRA loop
    23. mult:
    24. CLRB
    25. STAB $1350
    26. MOVB $1350, $1351 ; copy content of 1350(var) to 1351(res)
    27. ASL $1351
    28. ASL $1351
    29. LDAA $1351
    30. ADDA $1350 ; res += var;
    31. ASLA ; res << 1
    33. RTS
    35. halt:
    36. SWI
    Last edited by a moderator: Mar 14, 2016
  2. JohnInTX


    Jun 26, 2012
    The general method you are using multiplies the result by 10 then adds the new digit (0-9). I don't see that your code does that but I'm not too up on HC12 code these days either. I think your shift / accumulate operations are out of order.

    Also, make sure you are using the 16 bit register designations and not confusing with the 8 bit ones. For example, ASL shifts an 8 bit register, not 16 bits if I read the instruction set right. Your test number won't fit in 8 bits. ASLD may be what you are looking for - it shifts the A and B accumulators as a 16 bit register called D.

    The digit by digit accumulation procedure to variable n is

    n = (n*10) + new_digit.

    The multiplication is performed as (n*10) = (n*8) +( n*2)

    To do that:
    Shift n left once (n*2) and store that shifted result in a temp register ( n*2-> temp)
    Shift n left 2 more times (n*8)
    Add the temp register to the shifted n: (n*8)+(n*2), now n is multiplied by 10.
    Add the new digit (0-9) to n.

    If you have big numbers, you'll need to make n and temp big enough, 16 bits for an int (0-65535) and do double precision shifts and adds. I've attached some PIC assembler code (BCD2BIN.asm) that uses that *10 method, FWIW.

    I don't know why not. I think you are trying to keep everything in the registers when you should have it in RAM and use the registers for temp arithmetic. For example:
    Keep n in a 16 bit variable in RAM.
    c is the new digit in RAM(converted from ASCII )

    To add the new character:
    Move n (16bits) from RAM to index register Y (16 bits)
    Clear A, load B with 10decimal. (making D double accumulator made up of A|B = 10 i.e. $000A).
    EMUL ; Y*D = Y|D 16x16=32 bit result, D is the LS16 bits that you want - if Y<>0, its an overflow,
    D (A|B combined) = n*10 16 bits

    ADDB c ; add the 8 bit character in RAM to B
    BCC no_cy ; if no carry, done
    INCA ; else, propagate carry to A
    STD n ; store 16 bit double accumulator A:B to n, the result

    If you stored the new digit as 16bits (00 0d), you could make the addition easier by using
    ADDD c ; double accumulator AB += c
    instead of the 8 bit add and propagate carry. Lots of ways to skin this.

    Don't forget that you can PUSH registers on the stack for temporary storage - PUL to a register to use and be sure each PUSH has a corresponding PUL before the return.

    Finally, try to use equates in your code rather than literal values e.g. $1300. Its much easier to see what's going on and you are more likely to succeed.

    Good luck and welcome to AAC!
    EDIT: Removed double dabble method; Confusing the issue.
    Last edited: Mar 15, 2016
    snr likes this.