Page 1 of 1

Printing vendor string in real mode

Posted: Mon Feb 20, 2012 1:25 am
by Unkn0wn1
I want to be able to show the CPU's vendor string, obtained using the following

Code: Select all

xor eax, eax     ;EAX=0
cpuid     ;GET VENDOR STRING
According to a regdump, I'm fine with that, but my print from the 32 bit registers dosen't work.... And often it dosen't even recognise the command...

I use this code to print the vendor string

Code: Select all

mov esi, ebx
call print_string_e
mov esi, edx
call print_string_e
mov  esi, ecx
call print_string_e
the 32-bit register print is using this code, my first foray into direct hardware control (I'm in real mode, so have been using the BIOS)

Code: Select all

; ------------------------------------------------------------------
; print_c32 -- Displays A charater using 32-bit registers!
; IN: ESI = message location (zero-terminated string), ES = VIDMEM location (0xB800
; OUT: Nothing (registers preserved)

print_c32:
 mov ah, 0x0F   ; attrib = white on black
   mov cx, ax    ; save char/attribute
   movzx ax, byte [ypos]
   mov dx, 160   ; 2 bytes (char/attrib)
   mul dx      ; for 80 columns
   movzx bx, byte [xpos]
   shl bx, 1    ; times 2 to skip attrib
 
   mov di, 0        ; start of video memory
   add di, ax      ; add y offset
   add di, bx      ; add x offset
 
   mov ax, cx        ; restore char/attribute
   stosw              ; write char/attribute
   add byte [xpos], 1  ; advance to right
 
   ret

; ------------------------------------------------------------------
; print_string_e -- Displays A string using 32-bit registers!
; IN: ESI = message location (zero-terminated string),
; OUT: Nothing (registers preserved)
dochar:
call print_c32

	
print_str32:
 lodsb      ; string char to AL
   cmp al, 0
   jne dochar   ; else, we're done
   add byte [ypos], 1   ;down one row
   mov byte [xpos], 0   ;back to left
   ret
xpos db 0
ypos db 0
 ; ==============================================



Re: Printing vendor string in real mode

Posted: Mon Feb 20, 2012 1:45 am
by Solar

Re: Printing vendor string in real mode

Posted: Mon Feb 20, 2012 8:03 am
by bubach
Your print string function is expecting a _pointer_ to a zero terminated ASCII string. What you give it is raw ASCII chars in the register.

See the wiki.

You should do something like this after the CPUID:

Code: Select all

vendorstring db "            ",0   ; buffer

;cpuid code here

mov     dword [vendorstring], ebx
mov     dword [vendorstring+4], edx
mov     dword [vendorstring+8], ecx 

; print vendorstring here

Re: Printing vendor string in real mode

Posted: Mon Feb 20, 2012 8:23 am
by Solar
bubach wrote:What you give it is raw ASCII chars in the register.
Does he?

I see:
  • A piece of code calling cpuid;
  • A different piece of code calling a function named print_string_e;
  • Yet another piece of code implementing the function print_str32.
  • A misformatted code signature that doesn't terminate at the correct place if not on the sunny path, calling print_string (i.e., the third variation of print function)...
Since he's fuzzy about describing the problem, he might as well get linker errors about "undefined reference". ;-) (Just poking some fun at the OP. But nice catch, of course.)

Re: Printing vendor string in real mode

Posted: Mon Feb 20, 2012 8:53 am
by bubach
Solar wrote:
bubach wrote:What you give it is raw ASCII chars in the register.
Does he?
Yes, he moves the raw ASCII values that CPUID returns in EDX, ECX and EBX into ESI as if it where ASCIIZ pointers:
Unkn0wn1 wrote:I use this code to print the vendor string

Code: Select all

mov esi, ebx
call print_string_e
mov esi, edx
call print_string_e
mov  esi, ecx
call print_string_e
That's specific enough for me to provide an answer that might help. @OP: But it wouldn't hurt to include a comment about whether the print string function is confirmed to work in other cases. If it's faulty, this wont help you.

Re: Printing vendor string in real mode

Posted: Mon Feb 20, 2012 9:13 am
by Solar
bubach wrote:
Solar wrote:
bubach wrote:What you give it is raw ASCII chars in the register.
Does he?
Yes, he...
Yes, I got that. I just wanted to point out that his presentation of his problem leaves much to be desired, to the point of not allowing to say anything for certain (as the code he's showing is obviously not the code he's running).

Re: Printing vendor string in real mode

Posted: Mon Feb 20, 2012 11:20 am
by Unkn0wn1
Different Revisions of different files... ooops....

Thanks for the help, gonna try it momentarily (my image program is playing up ATM)
Oh, and @Solar, I don't use a linker, or LKMs or anything like that. My kernel is one main file, with several %INCLUDEd into it for neatness. As such, no link-errors

Re: Printing vendor string in real mode

Posted: Mon Feb 20, 2012 11:43 am
by Solar
Unkn0wn1 wrote:As such, no link-errors
Oh, but you will get errors because of undefined references, no?

That you get them from your assembler, not a seperate linker tool, doesn't change the fact that you get 'em. Your "call print_string_e" could not be linked to the address of an existing function.

But that's pointless pointification. Bottom line, if you ask for help debugging a piece of code, ideally that piece of code should be compilable. The process of getting a minimal working example is a large part of the art of debugging.

Re: Printing vendor string in real mode

Posted: Mon Feb 20, 2012 1:19 pm
by GAT
Just tried in as bubach said, and, for me at least, it seems to work.
here is my code:

Code: Select all

sysinfo:
vendorid times 13 db 0
mov eax,0
cpuid
mov [vendorid],ebx
mov [vendorid + 4],edx
mov [vendorid + 8],edx
mov si,vindorid
call print
ret

print:
pusha
mov ah,0Eh
.loop
lodsb
cmp al,0
je .done
int 10h
jmp .loop
.done
popa
ret
Seems to work in real mode just fine.

Re: Printing vendor string in real mode

Posted: Mon Feb 20, 2012 3:36 pm
by Unkn0wn1
GAT, just feel the need to mention that

Code: Select all

xor eax, eax
is faster than

Code: Select all

mov eax, 0
Probably imperceptible to the user, though :wink:

Re: Printing vendor string in real mode

Posted: Thu Feb 23, 2012 8:15 am
by brain
Unkn0wn1 wrote:GAT, just feel the need to mention that

Code: Select all

xor eax, eax
is faster than

Code: Select all

mov eax, 0
Probably imperceptible to the user, though :wink:
It's not just faster, it also uses less space :)

Re: Printing vendor string in real mode

Posted: Thu Feb 23, 2012 8:18 am
by Brendan
brain wrote:
Unkn0wn1 wrote:Probably imperceptible to the user, though :wink:
It's not just faster, it also uses less space :)
And also trashes flags - be careful if you're doing something like:

Code: Select all

    cmp eax,ebx
    xor edx,edx
    je .eax_equals_ebx
Cheers,

Brendan