Question

I am writing a toy OS, which is supposed to be a command line. I have tried adding CPUID to my functionality, and I get weird results when I call CPUID in consecutive order, i.e. 80000002h, 80000003h, 80000004h. If I call it in any other order, it works fine.

Consecutive order

Consecutive order

Another order:

Another order

This is the offending part of the code.

prcpuinf:
    push dx

    mov eax, 80000002h
    cpuid
    mov [es:cpuinfo+0], eax
    mov [es:cpuinfo+4], ebx
    mov [es:cpuinfo+8], ecx
    mov [es:cpuinfo+12], edx  

    mov eax, 80000003h
    cpuid
    mov [es:cpuinfo+16], eax
    mov [es:cpuinfo+20], ebx
    mov [es:cpuinfo+24], ecx
    mov [es:cpuinfo+28], edx
    mov eax, 80000004h
    cpuid
;    jmp prnt
    mov [es:cpuinfo+32], eax
    mov [es:cpuinfo+36], ebx
    mov [es:cpuinfo+40], ecx
    mov [es:cpuinfo+44], edx
    nop
prnt:

    mov ah, 13h    
    mov ecx, 48;cpulen
    mov bh, 0
    mov bl, 0x07
    mov dh, 3
    mov dl, 3
    mov bp, cpuinfo
    int 10h

    pop dx
    mov ecx, 1
    ret

The code behaves this way even if I don't copy the last part of the CPU Brand String, i.e. when uncommenting `jmp prnt.

Because this part works normally in a file by itself, I have posted my entire code here.

Please note, I am not looking for a solution, but rather for an explanation to what is happening.

Était-ce utile?

La solution

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 and BL specifies the attribute, do not update the cursor
  • AL=1h: BP is a character string and BL specifies the attribute, update the cursor
  • AL=2h: BP is a string of character-attribute pairs, do not update the cursor
  • AL=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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top