2

Here i have a assembly code that converts word value to string

; si -> Offset Address of String
; ax -> Number to be converted
itoa:
push ax ; Backup AX To Stack
push bx ; Backup BX To Stack
push dx ; Backup DX To Stack
push si ; Backup SI To Stack
mov bx,10 ; Set BX to 10 for Dividing the AX by 10
.loop:
    div bx ; Divide AX With BX For Getting The Digit And Removing First Digit Of Number
    add dl,48 ; Add 48 to DL to Convert Digit to Ascii
    mov [cs:si],dl ; Write digit to string
    xor dl,dl ; Set DX to 0
    inc si ; Increase SI
    cmp ax,0 ; Compare AX with 0
    jne .loop ; If ax not equals 0 then jump back to start of loop
pop si ; Get Backup Value of SI From Stack
pop dx ; Get Backup Value of DX From Stack
pop bx ; Get Backup Value of BX From Stack
pop ax ; Get Backup Value of AX From Stack
ret ; Return from Subroutine

When i run this code, it outputs reverse of number that given in AX, which is problem for me. How can i solve this ?

  • 2
    This method of converting to decimal inherently generates the digits in reverse order, as you have observed. Initialize si to the end of the buffer and decrement it after storing each digit. – prl Jan 03 '21 at 19:46

2 Answers2

2

I do it like this

utoa:
   mov  cx,10
nextdiv:
   xor  dx,dx
   div  cx
   push dx
   or   ax,ax
   jz   nextdigit
   call nextdiv
nextdigit:
   pop  ax
   add  al,30h
   mov  [si],al
   inc  si
   ret

It recurses on the stack, so it uses up to 10 words, one per digit plus the return value. I called it utoa because it's for unsigned, if you want the signed version (itoa) ask.

Arthur Kalliokoski
  • 1,627
  • 12
  • 12
1

Either output the characters one by one like in the examples in Displaying numbers with DOS, or else store from the end of the buffer and output the characters all at once. Don't forget to suitably terminate the buffer in this case.

Please note that in your present code you forgot to zero DX before the first division!

Converting a word can at most generate 5 characters, that's why I seek offset +5 in the buffer where the terminator goes right after the least significant digit.

  add  si, 5
  mov  byte [si], '$'
  mov  bx, 10
.loop:
  xor  dx, dx
  div  bx
  add  dl, 48      ; Add 48 to DL to Convert Digit to Ascii
  dec  si
  mov  [si], dl    ; Write digit to string
  test ax, ax
  jnz  .loop

Here SI points to the start of the string. You could print this via:

mov  dx, si
mov  ah, 09h   ; DOS.PrintString
int  21h
Sep Roland
  • 33,889
  • 7
  • 43
  • 76