0

I'm working on my first program that does some calculations and the result store in AL register. I have a problem with my converting from HEX to ASCII subroutine to print it to screen. So, If the value in AL between 0 and 9, it print the ASCII value with no problems. The problem is if the value in AL bigger than 9, I got 3 zeros printed. Please, any comment might help. This is my code:

FNUM    DB  20 Dup ?

B2A8:
     LEA    DI, FNUM        ;point DI to ASCII save
     MOV    W[DI], 3030H    ;preload ASCII buffer with number bias
     MOV    B[DI+2], 30H
B2A1:
     SUB    AL, 100     ;subtract 100's placeholder value
     JC     B2A2        ;if negative, we subtracted too much
     INC    B[DI]       ;if positive, add 1 to ASCII byte
     JMP    B2A1        ;continue counting place values until minus
B2A2:
     ADD    AL, 100     ;restore AL to previous value over subtracted
B2A3:
     SUB    AL, 10      ;subtract 10's placeholder value
     JC     B2A4        ;if negative, we subtracted too much
     INC    B[DI+1]     ;if positive, add 1 to ASCII byte
     JMP    B2A3        ;continue counting place values until minus

B2A4:

     ADD    AX, 10      ;restore AL to previous value over subtracted
     ADD    [DI+2], AL  ;create units character
     MOV    B[DI+3], '$'    ;mark end of the text
     RET
  • what do you mean by hex and what do you mean by ascii? do you mean binary to ascii? (show an example in words what your input looks like and the expected output) what is your range of values? (are you doing signed or unsigned comparisons?) why not just use divide? – old_timer May 03 '17 at 05:45
  • on the first look, your function should work ... are you sure you're loading AL with the value you want to convert before calling it? – Tommylee2k May 03 '17 at 06:32
  • Which assembler? – rkhb May 03 '17 at 07:23
  • What assembler is this that allows `B` and `W` instead of `BYTE` and `WORD`? Also, a couple of unrelated notes: (1) You don't have to write assembly in all caps, and in fact, you shouldn't because it makes it hard to read. (2) `LEA DI, FNUM` is equivalent to `MOV DI, OFFSET FNUM` (or whatever the syntax is for `OFFSET` in your assembler), but the latter is probably more efficient. (3) You should consider using `JB` instead of `JC`. They are identical, of course, but I think "jump-if-below" is more obvious after a `SUB` operation. – Cody Gray - on strike May 03 '17 at 12:13
  • As for the problem with your code, one jumps out at me immediately: after you "preload ASCII buffer", you fall through to `B2A1` (seriously, these label names should be human-readable!), and immediately try and start using `AL`. Except that you never initialized `AL` to anything! You could have seen this easily if you had stepped through this code with a debugger: `AL` would contain garbage! Using a debugger will also help you fix the code if that is not the only problem. – Cody Gray - on strike May 03 '17 at 12:14
  • @CodyGray: `B` and `W` is allowed at least in A86, A386 and GoAsm. – rkhb May 03 '17 at 17:23

0 Answers0