Binary values in hexidecimal notation written directly to video memory In X86 Legacy boot loader prologue the first seven instructions preserve the state of the 8 general purpose and 6 segment registers. This is where they are displayed, right justified without leading zeros. Most often you'll see this kind of thing formulated as an ASCII string, then displayed with printf or maybe if INT 80 or SYSCALL under Linux.

The addresses are absolute and for those that may be interested in executing the code, you can PM me and I'll send the current version that can be assembled with NASM. Then breakpoints can be set and in my case I use BOCH's.

Here is the result;

SI is already pointing to the beginning of this string


  'AXCXDXBXSPBPSIDIESDSCSSSFSGS'


 700  83C61B            add     si, 27     Point to last character
 703  FD                std                Do things in reverse
 704  6800B8            push    VIDEO_SEG
 707  07                pop     es
 708  BF9C09            mov     di, 0x99c  Row 15 Column 30 (zero indexed)
 70B  B90E00            mov     cx, 14     Values to be displayed
 70E  B407              mov     ah, 0x7    in low intensity white


At this point SP is pointing to the values preserved in proglogue.



that is why this instruction without the corresponding push works. After all, is said and done, SS:SP will be pointing to the far pointer back into the BIOS.

 710  5A                pop     dx      Retrieve registers value


Retain pointer to end of hex value (DI) and in case we change attribute which is in AH, preserve it too.

 711  57                push    di
 712  50                push    ax            AH = White
 713  09D2              or      dx, dx        Is value zero
 715  7502              jnz     719
 717  FEC4              inc     ah            AH = Grey
 719  E8BFFF            call    6db


Now registers mnemonic can be displayed in bright yellow

 71C  B40E              mov     ah, 14        Attribute bright yellow
 71E  AC                lodsb
 71F  AB                stosw
 720  AC                lodsb
 721  AB                stosw

 722  58                pop     ax            AH = White again
 723  5F                pop     di
 724  81EFA000          sub     di, 160       Bump pointer up one line
 728  FEC9              dec     cl          
 72A  740A              jz      736           Bail if done ZF=1


As soon as CL = 8, that means all the segment registers have been displayed and we can move over to the next column

 72C  80F908            cmp     cl, 8
 72F  75DF              jnz     710
 731  BF200A            mov     di,0xa20      DI = 5DC 
 734  EBDA              jmp     710


One thing I had considered here is adding 444H to DI instead, which in effect does exactly the same and then the left column would stay relative if the word at 709H was changed.

Finally, restore DF

 736  FC                cld




This is where DX will be right justified without leading spaces

 6DB  51                push    cx
 6DC  B105              mov     cl, 0x5

 Converts low nibble in AL to corresponding 0-1 or A-F
 6DE  88D0              mov     al, dl
 6E0  240F              and     al, 0xf
 6E2  3C0A              cmp     al, 0xa
 6E4  7202              jc      6e8
 6E6  0407              add     al, 0x7
 6E8  0430              add     al, 0x30
 6EA  AB                stosw
 6EB  FEC9              dec     cl

 Asserting DX here assures only one zero will be displayed for zero
 values in DX
 6ED  C1EA04            shr     dx, 4
 6F0  75EC              jnz     6de
 6F2  D1E1              shl     cx, 1
 6F4  29CF              sub     di, cx
 6F6  B82D0F            mov     ax, 0xf2d
 6F9  66AB              stosd                  Write bright white hyphen
 6FB  59                pop     cx
 6FC  C3                ret
This is a very nice routine that totally succeeds in using a direction flag set to 1. I've seen others fail at this.

Some observations:


731  BF200A            mov     di,0xa20      DI = 5DC 



It's not clear what you mean with "DI = 5DC"


  One thing I had considered here is adding 444H to DI instead, which in effect does exactly the same and then the left column would stay relative if the word at 709H was changed.


I would definitely choose adding 444h to DI in such a specially crafted routine. Relative addressing is so much more flexible to work with.


6F6  B82D0F            mov     ax, 0xf2d
6F9  66AB              stosd                  Write bright white hyphen



This is the only place where your code conceivably could fail. You store the dword from EAX without making sure the high word has any meaningful content. If the high word is empty you're in the clear, if not the screen will get disrupted.
Since modern BIOSes do use 32-bit registers, you can't be sure...

The shortest way to 'correct' this is:

mov     ax, 0x0F2D
stosw
dec     di
dec     di