Short answer: always specify AX
entirely.
Let's look at this piece of code:
mov ah, 13h
mov ecx, 48;cpulen
mov bh, 0
mov bl, 0x07
mov dh, 3
mov dl, 3
mov bp, cpuinfo
int 10h
You defined AH
, BX
, CX
, DX
, and BP
. You didn't define AL
, which is also part of the interface for INT 10h
. In case of AH=13h
, AL
specifies the subservice, as mentioned in this question:
AL=0h
:BP
is a character string andBL
specifies the attribute, do not update the cursorAL=1h
:BP
is a character string andBL
specifies the attribute, update the cursorAL=2h
:BP
is a string of character-attribute pairs, do not update the cursorAL=3h
:BP
is a string of character-attribute pairs, update the cursor
I think that actual implementations just look at the least significant bits of AL
, and decide what to do. Specifically, in your case, whenever bit 1 of AL
is set, you see the garbled text, but when it's reset, you see the normal text.
So whether you see garbled or normal text depends on what the last call to CPUID
wrote to bit 1 of AL
. This is exactly why it depends on the order of calls.