Page 1 of 1

Displaying Contents of Registers

Posted: Mon Nov 05, 2007 5:27 pm
by karsk
I'm just starting my very own OS, but I have a question. I've been searching everywhere, but I can't find any way to display the contents of a register on the screen. Anyone know how to do that? I'm in Real Mode now, but I also would like to know how to do it in protected mode.

I already know how to print a character from a memory location like this...

Code: Select all

mov message, %si
mov $0x0E, %ah
   xor %bx, %bx
1:
   lodsb
   or %al, %al
   jz 2f

   int $0x10
   jmp 1b
2:
   xor %si, %si
...but that's it.

I realize that firing this interrupt uses whatever's in the %al register, but it converts it to ASCII.

So what I'm saying is, is there a way to just do the equivalent of "echo %ax" and it echoes something like "1010101010101010" on the screen?

Thanks.

Posted: Tue Nov 06, 2007 2:09 am
by Solar
  • have an array "0123456789ABCDEF" somewhere in memory;
  • have a function that takes the "nibbles" (half-bytes) of a register in turn and uses them as index into the array, printing the value;
  • enjoy your register contents, printed as hexadecimal.
How to take nibbles of EAX:
  • AH, 4 right-shifts
  • AH, AND 0x0f
  • AL, 4 right-shifts
  • AL, AND 0x0f
"The actual implementation is left as an exercise to the reader."

Posted: Tue Nov 06, 2007 2:51 pm
by karsk
Thanks alot, I never would have thought of that! :D

Posted: Tue Nov 06, 2007 3:08 pm
by XCHG
One technique that you can use (I think I am the only one who uses this though lol), let's say you have a 32-bit value in EAX and you want to print it as hexadecimal letters. Instead of shifting to the right and left, just ROL EAX 4 bits. So the most significant nibble in EAX will be placed in the least significant nibble. Then do a simple MOV to move EAX to another 32-bit register. AND that register with 0x0000000F and then print that character into the string (convert it to a character first). That way, for the next nibble, you will continue with the same operation (ROL EAX , 4). Then when all the ROLs are done (8 ROLs because we have 8 nibbles in a 32-bit value), you will have your original EAX back in EAX. That's the good thing about rotation in comparison to shifting.

This is how I do it in my Operating System:

Code: Select all

; --------------------------------------------------
  __DWORDToHexExact:
    ; void __DWORDToHexExact (DWORD InDWORD, char* Buffer); StdCall;
    PUSH    EAX
    PUSH    EBX
    PUSH    ECX
    PUSH    EDX
    PUSH    EBP
    MOV     EBP , ESP
    ; EAX = InDWORD
    MOV     EAX , DWORD PTR [EBP + 0x18]
    ; EBX = Buffer
    MOV     EBX , DWORD PTR [EBP + 0x1C]
    ; 8 Hexadecimal letters to convert
    MOV     ECX , 0x00000008
    .Loop:
      ROL     EAX , 0x04
      MOV     EDX , EAX
      AND     EDX , 0x0000000F
      CMP     EDX , 0x0000000A
      JB      .IsDigit
      ADD     EDX , 0x00000007
      .IsDigit:
        ADD     EDX , 0x00000030
        MOV     BYTE PTR [EBX] , DL
        INC     EBX
        DEC     ECX
        JNZ     .Loop
    .EP:
      MOV     BYTE PTR [EBX] , 0x00
      POP     EBP
      POP     EDX
      POP     ECX
      POP     EBX
      POP     EAX
    RET   0x08
; --------------------------------------------------

Posted: Tue Nov 06, 2007 7:52 pm
by karsk
Thank you for your reply as well, that is another way of doing it. Albeit with a little more work.... :)