1

Can anyone assist with my understanding of these directions? I'm currently learning x86 Assembly, but I cannot seem to display the output I'm looking for. I understand AL contains the byte I need to display..but how can I display the correct output, considering these requirements:

I am getting stuck on WriteChar for DH and DL, as the output I'm looking for with my solution does not appear to be correct...I can't tell what I'm missing. I can initialize AL and DL/DH correctly, but when I use WriteChar, it prints a completely different character.

  1. store in the register DH the ASCII code of the most significant nibble.
  2. store in the register DL the ASCII code of the least significant nibble.
  3. Display (using WriteChar) on the console the character stored in DH (recall that WriteChar uses AL for the character to display).
  4. Display (using WriteChar) on the console the character stored in DL.
  5. Display ‘h’ to indicate that the number is a hexadecimal number.
  6. ‘Display’ the ‘line feed’ character (ASCII code is 0Ah) to go to the next line.
  7. ‘Display’ the ‘carriage’ character (ASCII code is 0Dh) to go to the next line.

Here is an example and below that is what I have so far...

Example : If AL contains the number 94h, your program 1) must store 39h (ASCII code of the character ‘9’) in DH , 2) must store 34h (ASCII code of the character ‘4’) in DL, 3) must display the characters ‘9’, ‘4’, ‘h’, ‘linefeed’, and ‘carriage return’.

Code Attempt:

INCLUDE Irvine32.inc
.data 
   myHex BYTE "h", 0 
.code
ExerciseTwo proc
   MOV EAX, 0
   MOV AL, 94h
   CALL WriteChar
   MOV DH, AL
   SHR DX, 4
   SHR DL, 4 
   
   MOV EDX, OFFSET myHex
   CALL WriteString
   
   invoke ExitProcess, 0 
ExerciseTwo endp 
end ExerciseTwo
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
TheBMAN
  • 69
  • 5
  • 1
    Uou aare calling `WriteChar` too early. When you have the most significant nibble in DH (after the two `SHR`s) you need to convert its value (09h) to hexadecimal digit (39h), copy it to AL and `CALL Writechar`. Repeat with the second value (04h). and finally with characters `'h'`, `0Ah` and `0Dh`. – vitsoft Nov 05 '21 at 19:17
  • Ah I put the WriteChar earlier to test what happens after using it. See, now that's where I'm having trouble...I can see EDX containing 00400 0904, which means the SHR works just fine. But, how would I go about extracting that 09 in DH to convert to hex? I think I'm getting confused with the 09->39h bit. If DH = 09, how would that convert to 39h? Because the char '9' = 39h, not 09h. – TheBMAN Nov 05 '21 at 19:56
  • 1
    **If DH is not above 9**, simply `ADD DH,'0'`, this will convert the value 9 to (hexa)decimal digit **'9'**. **Otherwise** `ADD DH,,'0'+7`, this will convert the value 10 to hexadecimal digit (letter) **A**., value 11 to **B** etc. – vitsoft Nov 05 '21 at 20:26
  • Thank you! I guess my last question is why does adding '0' to the MSN 09h in EDX convert it to the character '9'? – TheBMAN Nov 05 '21 at 20:54
  • 1
    Because the ASCII code for the character "9" is 39h which is precisely 30h more than 9. And 30h is the ASCII code for the character "0". – Sep Roland Nov 05 '21 at 20:57
  • I think the lightbub just went off thanks to you...genuinely hadn't thought of it in that way. That actually helps a bunch! – TheBMAN Nov 05 '21 at 21:04
  • Related: [How to convert a binary integer number to a hex string?](https://stackoverflow.com/q/53823756) for 32-bit integers. – Peter Cordes Nov 06 '21 at 14:42

1 Answers1

3

Hex conversion from numbers 0 to 9 involves adding 48 to get to "0" to "9"
Hex conversion from numbers 10 to 15 involves adding 55 (48 + 7) to get to "A" to "F"

INCLUDE Irvine32.inc
.data 
   myHex BYTE "h", 10, 13, 0      ; include 10 and 13 here
.code
ExerciseTwo proc
   mov  eax, 94h                  ; in 1 instruction
   MOV  DH, AL
   SHR  DX, 4
   SHR  DL, 4 

   mov  al, dh
   call WriteHexDigit             ; use subroutines to not repeat yourself
   mov  al, dl
   call WriteHexDigit

   MOV  EDX, OFFSET myHex
   CALL WriteString
   invoke ExitProcess, 0 

WriteHexDigit:
   add al, '0'                    ; operations on AL use shorter encodings
   cmp al, '9'
   jbe ok1
   add al, 7
 ok1:
   jmp WriteChar                  ; tail-call replaced by jump

ExerciseTwo endp ```
Sep Roland
  • 33,889
  • 7
  • 43
  • 76