Amirhossein Sharifloo
Amirhossein Sharifloo

Reputation: 55

printing digits in assembly 8086

I've written this code using some instructions I found on the Internet to convert some digits which has been calculated by assembly program and then stored in a register or storage. THen I can not cannot figure out how to print SI which contains converted number. I think I need to find a way to go back in the SI, and save the data first. Has anyone have got any Ideas?

;CONVERTING DIGITS 


MOV  AX, HORIZONTAL
MOV  BX, 10         ;DIGITS ARE EXTRACTED DIVIDING BY 10.
MOV  CX, 0          ;COUNTER FOR EXTRACTED DIGITS.

CYCLE1:       
MOV  DX, 0          ;REMAINDER OF DIV WILL BE STORED HERE
DIV  BX             ;DX:AX / 10 = AX:QUOTIENT DX:REMAINDER.
PUSH DX             ;PRESERVE DIGIT EXTRACTED FOR LATER.
INC  CX             ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED. 

CMP  AX,0           ;TO SEE IF NUMBER IS
JNE  CYCLE1         ;NOT ZERO, LOOP BACK. 

;NOW RETRIEVING PUSHED DIGITS.

MOV  SI, OFFSET HORIZONTAL  
MOV  TMP1, CX
CYCLE2:  
POP  DX        
ADD  DL, 48    ;CONVERT DIGIT TO CHARACTER.
MOV  [SI], DL
INC  SI
LOOP CYCLE2


MOV AH,9            ; print string
MOV DX, OFFSET SI
INT 21h

Upvotes: 2

Views: 4257

Answers (2)

Your code is almost perfect, it just needs another variable for the string, copy-paste next code in EMU and run :

.model small
.stack 100h
.data

HORIZONTAL DW 61503  ;◄■■ TEST NUMBER.
RESULT     DB 6 DUP('$') ;◄■■ VARIABLE FOR THE STRING ☻.
TMP1       DW ?

.code
  mov  ax, @data
  mov  ds, ax

;CONVERTING DIGITS ( ▼ YOUR CODE ▼ ).

MOV  AX, HORIZONTAL
MOV  BX, 10         ;DIGITS ARE EXTRACTED DIVIDING BY 10.
MOV  CX, 0          ;COUNTER FOR EXTRACTED DIGITS.

CYCLE1:       
MOV  DX, 0          ;REMAINDER OF DIV WILL BE STORED HERE
DIV  BX             ;DX:AX / 10 = AX:QUOTIENT DX:REMAINDER.
PUSH DX             ;PRESERVE DIGIT EXTRACTED FOR LATER.
INC  CX             ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED. 

CMP  AX,0           ;TO SEE IF NUMBER IS
JNE  CYCLE1         ;NOT ZERO, LOOP BACK. 

;NOW RETRIEVING PUSHED DIGITS.

MOV  SI, OFFSET RESULT ;◄■■ VARIABLE FOR THE STRING.
MOV  TMP1, CX
CYCLE2:  
POP  DX        
ADD  DL, 48    ;CONVERT DIGIT TO CHARACTER.
MOV  [SI], DL
INC  SI
LOOP CYCLE2


MOV AH,9            ; print string
MOV DX, OFFSET RESULT ;◄■■ VARIABLE FOR THE STRING.
INT 21h

  mov  ax, 4c00h
  int  21h

Upvotes: 2

Cody Gray
Cody Gray

Reputation: 244692

For DOS service 09h, which prints a string to the standard output, DS:DX should contain a pointer to to the $-terminated string. So you have two tasks in order to print the string:

  1. Add a $ character to the end of the string to mark its end.
  2. Place a pointer to the beginning of the string in the DX register.

Your current code is wrong because it doesn't do either of these two things. Remember that, while the SI register does contain a pointer, after the loops are done, it contains a pointer to the end of the string, which is not what you want. You need a pointer to the beginning of the string. Fortunately, HORIZONTAL is the offset of the beginning of the string buffer, so you can just use that! (The segment register, DS, doesn't need to change.)

So, what your code needs to look like is:

; Terminate string
mov  BYTE PTR [si], '$'

; Print string
mov  dx, OFFSET HORIZONTAL
mov  ah, 09h
int  21h

Upvotes: 1

Related Questions