Printing vendor string in real mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Unkn0wn1
Member
Member
Posts: 37
Joined: Fri Jan 13, 2012 11:18 am

Printing vendor string in real mode

Post 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
 ; ==============================================


Not sane
Just remember, FIND Is Not DOS :)
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Printing vendor string in real mode

Post by Solar »

Every good solution is obvious once you've found it.
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re: Printing vendor string in real mode

Post 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
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Printing vendor string in real mode

Post 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.)
Every good solution is obvious once you've found it.
User avatar
bubach
Member
Member
Posts: 1223
Joined: Sat Oct 23, 2004 11:00 pm
Location: Sweden
Contact:

Re: Printing vendor string in real mode

Post 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.
"Simplicity is the ultimate sophistication."
http://bos.asmhackers.net/ - GitHub
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Printing vendor string in real mode

Post 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).
Every good solution is obvious once you've found it.
Unkn0wn1
Member
Member
Posts: 37
Joined: Fri Jan 13, 2012 11:18 am

Re: Printing vendor string in real mode

Post 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
Not sane
Just remember, FIND Is Not DOS :)
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Printing vendor string in real mode

Post 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.
Every good solution is obvious once you've found it.
User avatar
GAT
Member
Member
Posts: 75
Joined: Wed Nov 30, 2011 9:51 pm
Contact:

Re: Printing vendor string in real mode

Post 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.
d3: virtualizing kernel in progress
https://github.com/WizardOfHaas/d3/
Unkn0wn1
Member
Member
Posts: 37
Joined: Fri Jan 13, 2012 11:18 am

Re: Printing vendor string in real mode

Post 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:
Not sane
Just remember, FIND Is Not DOS :)
User avatar
brain
Member
Member
Posts: 234
Joined: Thu Nov 05, 2009 5:04 pm
Location: UK
Contact:

Re: Printing vendor string in real mode

Post 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 :)
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: Printing vendor string in real mode

Post 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
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply