Sean
Sean

Reputation: 11

convert string to decimal in assembly language

I'm trying to convert string to decimal and then add all the numbers up to that decimal(for example if number is 5, i need to add 1+2+3+4+5) and then print that number after converting it back to decimal.

I'm trying below steps, code is not complete, till now im just converting string to decimal and checking if it got converted, there is some error

title       fill in title 

;------------------------------------------------------------------------------
stacksg segment     para stack 'Stack'
    db 32 dup(0)


stacksg ends
;---------------------------------------------------------------------------------------------
datasg segment para 'Data'
paralst label byte
maxlen DB 20
actlen DB ?
indata DB 20 dup ('$')
strout DB "Enter a number between 1 and 20: $"
errors DB "USER ERROR$"
sum DB "The sum is: $"
datasg ends
;-----------------------------------------------------------------------------------
codesg segment para 'Code'
main    proc    far
assume ss:stacksg, ds:datasg, cs:codesg 
mov ax, datasg ;initialize data segment registers
        mov ds, ax
        mov es, ax

        MOV AH, 06H
        MOV AL, 0
        MOV CX, 0  ; ch-row, cl-columns
        MOV DH, 79
        MOV DL, 79

        MOV BH, 01000000B

        int 10H

        Mov AH, 02H
        MOV BH, 00H
        MOV DH, 12  ; or mov dx 0c28h
        MOV DL, 25
        INT 10H

        MOV AH, 09H
        LEA DX, STROUT
        INT 21H

        Mov AH, 0AH
        LEA DX, paralst
        int 21H

;converting string to decimal

         CALL READ_NUM 

     READ_NUM Proc Near

        push BX
        push CX
        push DX

        LEA BX, indata
        Mov AX, 0
        Mov CX, 0
        Mov DL, 10

        again: 
        MOV CL, [BX]
        CMP CL, 0DH
        JE THEEND
        SUB CX, 30H
        MUL DL
        ADD AX, CX
        INC BX

        THEEND: 

        POP DX
        POP CX
        POP BX ; conversion complete

        CMP AX, 20  ; since converted decimal is in AX,
                    ; i am checking if it is over 20 or below 1....
                    ; there is where i get error.
        JG ERRS
        CMP AX, 1
        JL ERRS
        mov     ax, 4c00h   
        int 21h


        MOV DX, 0
        MOV CX, 1

        TOPPY:

        CMP DX, AX
        JG ENDDY
        ADD CX, DX
        INC DX
        JMP TOPPY



        ERRS:

        Mov AH, 02H
        MOV BH, 00H
        MOV DH, 15  ; or mov dx 0c28h
        MOV DL, 25
        INT 10H

        MOV AH, 09H
        LEA DX, errors
        INT 21H

        mov     ax, 4c00h   
        int 21h


        ENDDY:
        Mov AH, 02H
        MOV BH, 00H
        MOV DH, 16  ; or mov dx 0c28h
        MOV DL, 25
        INT 10H

        MOV AH, 09H
        LEA DX, sum
        INT 21H

                mov ax, 4c00h   
        int 21h

        Ret
        READ_NUM endp

        main endp       ;end of procedure


        codesg ends ;end of code segment    
        end main    ;end of program

Upvotes: 0

Views: 2411

Answers (1)

Fifoernik
Fifoernik

Reputation: 9899

    LEA BX, indata
    Mov AX, 0
    Mov CX, 0
    Mov DL, 10

   again: 
    MOV CL, [BX]
    CMP CL, 0DH
    JE THEEND
    SUB CX, 30H
    MUL DL
    ADD AX, CX
    INC BX

  THEEND: 

You've got some errors here:

  1. You don't actually do a loop in this code. A jump to again is missing.
  2. You forgot that it is a subroutine (that you called) and so you have to return from it using the ret instruction.
  3. The required READ_NUM endp is much too far down in the program.

Could it be that points 2 and 3 come from your debugging efforts?

READ_NUM Proc Near
  push bx
  push cx
  lea  bx, indata
  mov  al, 0      ;Clear result
again: 
  mov  cl, 10
  mul  cl         ;AX = AL * CL
  mov  cl, [bx]
  cmp  cl, 13
  je   THEEND
  sub  cl, '0'
  add  al, cl     ;Add in new digit
  adc  ah, 0
  inc  bx
  jmp  again      <<<< you missed this one!!
THEEND: 
  pop  cx
  pop  bx         ;Conversion complete
  ret             <<<< you missed this one!
READ_NUM endp

Please move the whole READ_NUM proc to below the DOS.Terminate so your code doesn't fall through into it accidentally:

  mov ax, 4C00h   
  int 21h

READ_NUM Proc Near
  push bx

paralst label byte
maxlen DB 20
actlen DB ?
indata DB 20 dup ('$')

Since you're asking for a numerical input between 1 and 20, you could choose to limit this buffer to 2 characters. This would allow for an input of no more than 99. Using a byte-sized multiplication your algorithm can only support numbers from 0 to 255 anyway.

paralst label byte
maxlen DB 3          ;2 characters and 1 carriage return
actlen DB ?
indata DB 3 dup (0)

  CMP AX, 20  ; since converted decimal is in AX,
                ; i am checking if it is over 20 or below 1....
                ; there is where i get error.
    JG ERRS
    CMP AX, 1
    JL ERRS
    mov     ax, 4c00h   
    int 21h

Even without the necessary jmp again should this debugging addition have worked well with a single digit input.


  MOV DX, 0
    MOV CX, 1

   TOPPY:

   CMP DX, AX
    JG ENDDY
    ADD CX, DX
    INC DX
    JMP TOPPY

The calculation of the sum of the numbers up to the inputted one is wrong. The number 1 is added twice!
See below that it's much simpler if you start adding from the top down:

               ;AX=5 (input)
 xor cx, cx
more:
 add cx, ax    ;+5 +4 +3 +2 +1
 dec ax
 jnz more
               ;CX=15

To print this 2-digit result you could read this.

Upvotes: 2

Related Questions