3

The following is my code. The block in hex2dec works successfully for converting a single hexadecimal number to decimal number. It would be really helpful if someone could point out where I was going wrong in the use of array. Thanks.

DATA SEGMENT
    NUM DW 1234H,9H,15H
    RES DB 3*10 DUP ('$','$','$')
    SIZE DB 3
DATA ENDS

CODE SEGMENT
    ASSUME DS:DATA, CS:CODE
START:
    MOV AX, DATA
    MOV DS,AX
    MOV DI,0
  LOOP3:
    MOV AX,NUM[DI]
    LEA SI,RES[DI]
    CALL HEX2DEC
    LEA DX,RES[DI]
    MOV AH,9
    INT 21H
    INC DI
    CMP DI,3
    JL LOOP3
    MOV AH,4CH   ; end program
    INT 21H
CODE ENDS

HEX2DEC PROC NEAR
    MOV CX,0
    MOV BX,10
  LOOP1:
    MOV DX,0
    DIV BX
    ADD DL,30H
    PUSH DX
    INC CX
    CMP AX,9
    JG LOOP1
    ADD AL,30H
    MOV [SI],AL
  LOOP2:
    POP AX
    INC SI
    MOV [SI],AL
    LOOP LOOP2
    RET
HEX2DEC ENDP
END START
zx485
  • 28,498
  • 28
  • 50
  • 59
Anurag
  • 33
  • 2
  • 5

1 Answers1

2
MOV AX,NUM[DI]
LEA SI,RES[DI]
LEA DX,RES[DI]

You are treating DI as an array index like we use in any of the high level languages. In assembly programming we only use displacements aka offsets in the array.

In your program, since the NUM array is composed of words, you need to give the DI register successively the values 0, 2, and 4.

ADD  DI, 2
CMP  DI, 6
JB   LOOP3

Also it would be best to not treat the RES as an array. Just consider it a buffer and always use it from the start.

RES  DB  10 DUP (0)
...
LEA  SI, RES
CALL HEX2DEC
LEA  DX, RES

A better version of HEX2DEC avoids the ugly prefixed "0" on the single digit numbers:

HEX2DEC PROC NEAR
    XOR  CX, CX        <--- Same as MOV CX,0
    MOV  BX,10
LOOP1:
    XOR  DX, DX        <--- Same as MOV DX,0
    DIV  BX
    ADD  DL, 30H
    PUSH DX
    INC  CX
    TEST AX, AX
    JNZ  LOOP1
LOOP2:
    POP  AX
    MOV  [SI], AL
    INC  SI
    LOOP LOOP2
    MOV  AL, "$"       <--- Add this to use DOS function 09h
    MOV  [SI], AL
    RET
HEX2DEC ENDP
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • I replaced the INC DI with ADD as suggested by you and also changed RES so that it always operates like a buffer. Still it gave the wrong answer. – Anurag Feb 12 '17 at 18:06
  • Did you terminate the string with a **$** character for each output? – Sep Roland Feb 12 '17 at 19:17
  • Are you sure that your assembler doesn't require you to write `MOV AX, @DATA` `MOV DS,AX` ? So adding the **@**. – Sep Roland Feb 12 '17 at 19:38
  • Thanks. The update to the HEX2DEC really helped it work. Still have to figure out why though. Guess that will take some time 1 doubt though. What purpose does the 'TEST AX, AX' serve in the function? – Anurag Feb 14 '17 at 18:05
  • The `test ax, ax` instruction is functionally the same as `cmp ax, 0`. You could have written: `CMP AX, 0` `JNE LOOP1` for looping as long as the `ax` not being zero. (Just like in your original question where you looped just as long the `ax` was greater than 9) – Fifoernik Feb 16 '17 at 11:29