assemblyx86irvine32

How to implement WriteHexByte in x86 Assembly?


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

Solution

  • 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 ```