PDA

View Full Version : Diagnostics



Charles Pegge
17-03-2009, 18:03
There are a number of ways to find out why a program does not compile. The o2_error message provides basic information and there are two forms of listing to show what the compiler has done with the source code. It is also possible to store the final binary product to fiile for inspection with a disassembler.

But o2_error provides basic information, and indicates where the error has occured (AFTER) a given label.





' DIAGNOSTICS

uses "oxygen","file"
dim src as string
src = "
o2h
dim i,j=1 as long
dim s,t as string
s=space 500
for i=1 to 10
t=str(i)+chr(13)+chr(10)
mid (s,j)=t
j+=len t
next
dec j
print left s,j
"
o2_basic src

'-------
'OUTPUTS
'=======

file_save ("s.txt", o2_prep "o2h "+src) ' o2 Assembler output
file_save ("t.txt", o2_view "o2h "+src) ' o2 script output
file_save ("t.bin", o2_get) ' o2 binary

if len(o2_error) then
msgbox 0, o2_error : stop
end if
o2_exec

Charles Pegge
17-03-2009, 18:10
#view ... #endv restricts the listing, so you can examine a line or two of code without getting lost in the rest of the code.






' DIAGNOSTICS
' CODE WINDOW #VIEW .. #ENDV

uses "oxygen","file"
dim src as string
src = "
o2h
dim i,j=1 as long
dim s,t as string
#VIEW
s=space 500
#ENDV
for i=1 to 10
t=str(i)+chr(13)+chr(10)
mid (s,j)=t
j+=len t
next
dec j
print left s,j
terminate
"
o2_basic src

msgbox 0, o2_view "o2h "+src

if len(o2_error) then
msgbox 0, o2_error : stop
end if
o2_exec

Charles Pegge
30-04-2009, 04:46
You can spy on the CPU / FPU / SIMD registers - taking snapshots while the code is running.



'
'TECHNIQUES FOR VIEWING REGISTERS
'
'these can be embedded in a program for testing & debugging

uses "oxygen"
dim s as string
s="

dim tab as string = chr 9

'---------
def SeeCPU
'=========
'
pusha
print `
CPU Registers:

EAX:` tab hex([esp+28]) `
ECX:` tab hex([esp+24]) `
EDX:` tab hex([esp+20]) `
EBX:` tab hex([esp+16]) `
ESP:` tab hex([esp+12]) `
EBP:` tab hex([esp+08]) `
ESI:` tab hex([esp+04]) `
EDI:` tab hex([esp+00]) `
`
popa
end def


'------------
sub SeeSimd()
'============
'
'CAPTURE SIMD REGS INTO ARRAY D()
'
dim as single d(32)
eax=&d
movups [eax ],xmm0
movups [eax+16],xmm1
movups [eax+32],xmm2
movups [eax+48],xmm3
movups [eax+64],xmm4
movups [eax+80],xmm5
movups [eax+96],xmm6
movups [eax+112],xmm7
dim as string s
s= `
SIMD Registers:

`
dim i,j=48
for i=1 to 32 step 4
s=s+ `XMM` chr(j) `:` +
tab str(d(i)) tab str(d(i+1)) +
tab str(d(i+2)) tab str(d(i+3)) `
`
inc j
next



print s
'
end sub

'--------------------------
function GetFPU() as string
'==========================
'
function=nuls 200
eax=*_function ' _function is internal name for function
fsave [eax+80]
frstor [eax+80]
fstp qword [eax+00]
fstp qword [eax+08]
fstp qword [eax+16]
fstp qword [eax+24]
fstp qword [eax+32]
fstp qword [eax+40]
fstp qword [eax+48]
fstp qword [eax+56]
frstor [eax+80]
end function

#view
#endv

'-----------------------------------
function PrintFPU(byval s as string)
'===================================
'
if len (s)<64 then print `no fpu data` : exit function
dim i=?s
dim as double d at i
print `
FPU Registers:

ST0:` tab str(d(1)) `
ST1:` tab str(d(2)) `
ST2:` tab str(d(3)) `
ST3:` tab str(d(4)) `
ST4:` tab str(d(5)) `
ST5:` tab str(d(6)) `
ST6:` tab str(d(7)) `
ST7:` tab str(d(8)) `
`
end function




'=========
'
'TESTS
'
'=========

mov eax,0
mov ecx,1
mov edx,2
mov edi,7
SeeCPU

dim s(10) as string
fld1 : fldpi : fldz : s(1)=GetFPU
fld1 : fldl2e : fldz : s(2)=GetFPU
PrintFPU s(1)
PrintFPU s(2)
finit

dim i
dim as single f(32)
'
'TEST DATA: FILL SIMD REGS
'
for i=1 to 32 : f(i)=i+i : next
'
eax=&f
'
movups xmm0,[eax ]
movups xmm1,[eax+16]
movups xmm2,[eax+32]
movups xmm3,[eax+48]
movups xmm4,[eax+64]
movups xmm5,[eax+80]
movups xmm6,[eax+96]
movups xmm7,[eax+112]
'
SeeSimd

"



'======================================

o2_basic s
if len(o2_error) then msgbox 0,o2_error
'msgbox 0,o2_view "o2h "+s
o2_exec

Charles Pegge
15-05-2009, 16:57
This program uses the cpuid instruction to extract information about yor PC's CPU.

It could be taken further by interpreting the cache codings - but I think these might be specific to Intel.

Thanks to Lionheart for sending me the initial code sample. :)

Charles

This is include in the latest Oxygen as cpuid.tbasic

http://community.thinbasic.com/index.php?topic=2517




'CPUID PROFILE

'INTEL CPUID GUIDE
'http://www.intel.com/assets/pdf/appnote/241618.pdf


uses "oxygen" ',"console"


dim p0,p1 as long
dim src as string

src="
o2h


Function Asm_support() As Integer at #p1

dim vendor(4),
features(4),
cache(4),
serial(4),
extFun(1),
extInfo(2),
brand(12),
extL2cache(2),
addrSizes(1)

push ebx : push esi

mov eax,&h0 : cpuid : lea edi,vendor
mov [edi+00],eax
mov [edi+04],ebx
mov [edi+08],edx
mov [edi+12],ecx

mov eax,&h1 : cpuid : lea edi,features
mov [edi+00],eax
mov [edi+04],ebx
mov [edi+08],ecx
mov [edi+12],edx

mov eax,&h2 : cpuid : lea edi,cache
mov [edi+00],eax
mov [edi+04],ebx
mov [edi+08],ecx
mov [edi+12],edx

'Pentium III only
'mov eax,&h3
'cpuid
'lea edi,serial
'mov [edi+00],eax
'mov [edi+04],ebx
'mov [edi+08],ecx
'mov [edi+12],edx

mov eax,&h80000000 : cpuid : lea edi,extFun
mov [edi+00],eax

mov eax,&h80000001 : cpuid : lea edi,extInfo
mov [edi+08],ecx
mov [edi+12],edx


mov eax,&h80000002 : cpuid : lea edi,brand
mov [edi+00],eax
mov [edi+04],ebx
mov [edi+08],ecx
mov [edi+12],edx
mov eax,&h80000003
cpuid
mov [edi+16],eax
mov [edi+20],ebx
mov [edi+24],ecx
mov [edi+28],edx
mov eax,&h80000004
cpuid
mov [edi+32],eax
mov [edi+36],ebx
mov [edi+40],ecx
mov [edi+44],edx

mov eax,&h80000006 : cpuid : lea edi,extL2cache
mov [edi+00],ecx

mov eax,&h80000008 : cpuid : lea edi,AddrSizes
mov [edi+00],eax


pop esi : pop ebx
'



dim d
dim as string s
dim as string cr
cr=`
`
'
'FEATURES
'--------
'
's+=`INTEL CPU TYPE: ` str(features(2) and 255 )+cr+cr

d=features(4) 'EDX

if d and 1 then s=s+`FPU `+cr
if d and 2 then s=s+`VME `+cr
if d and 4 then s=s+`DE `+Cr
if d and 8 then s=s+`PSE `+cr
if d and 0x10 then s=s+`TSC `+cr
if d and 0x20 then s=s+`MSR `+cr
if d and 0x40 then s=s+`PAE `+cr
if d and 0x80 then s=s+`MCE `+cr

if d and 0x100 then s=s+`CXB `+cr
if d and 0x200 then s=s+`APIC `+cr
'0X400
if d and 0x800 then s=s+`SEP `+cr
if d and 0x1000 then s=s+`MTRR `+cr
if d and 0x2000 then s=s+`PGE `+cr
if d and 0x4000 then s=s+`MCA `+cr
if d and 0x8000 then s=s+`CMOV `+cr
if d and 0x10000 then s=s+`PAT `+cr
if d and 0x20000 then s=s+`PSE-36 `+cr
if d and 0x40000 then s=s+`PSN `+cr
if d and 0x80000 then s=s+`CLFLUSH`+cr
'0x100000
if d and 0x200000 then s=s+`DS `+cr
if d and 0x400000 then s=s+`ACPI `+cr
if d and 0x800000 then s=s+`MMX `+cr
if d and 0x1000000 then s=s+`FXSR `+cr
if d and 0x2000000 then s=s+`SSE `+cr
if d and 0x4000000 then s=s+`SSE2 `+cr
if d and 0x8000000 then s=s+`SS `+cr
if d and 0x10000000 then s=s+`HTT `+cr
if d and 0x20000000 then s=s+`TM `+cr
if d and 0x40000000 then s=s+`IA64 `+cr
if d and 0x80000000 then s=s+`PBE `+cr

s+=cr+cr

d=features(3)

if d and 1 then s=s+`SSE3 `+cr
'0x2
if d and 4 then s=s+`DTES64`+cr
if d and 8 then s=s+`MONITOR`+cr
if d and 0x10 then s=s+`DS-CPL`+cr
if d and 0x20 then s=s+`VMX `+cr
if d and 0x40 then s=s+`SMS `+cr
if d and 0x80 then s=s+`EST `+cr

if d and 0x100 then s=s+`TM2 `+cr
if d and 0x200 then s=s+`SSSE3 `+cr
if d and 0x400 then s=s+`CNXT-ID`+cr
'0x800
'0x1000
if d and 0x2000 then s=s+`CMPXCHG16B`+cr
if d and 0x4000 then s=s+`xTPR `+cr
if d and 0x8000 then s=s+`PDCM `+cr
'0x10000
'0x20000
if d and 0x40000 then s=s+`DCA `+cr
if d and 0x80000 then s=s+`SSE4-1 `+cr
if d and 0x100000 then s=s+`SSE4-2`+cr
if d and 0x200000 then s=s+`X2APIC`+cr
if d and 0x400000 then s=s+`MOVBE `+cr
if d and 0x800000 then s=s+`POPCNT`+cr
'0x1000000
'0x2000000
if d and 0x4000000 then s=s+`XSAVE `cr
if d and 0x8000000 then s=s+`OSXSAVE`+cr
'0x10000000
'0x20000000
'0x40000000
'0x80000000

dim p1,p2
dim as zstring vendorz at p1
p1=&vendor +4
dim as zstring brandz at p2
p2=&brand

#view

print,

`CPUID` cr cr+
vendorz cr cr+
brandz cr cr+
`Features:` cr cr+
s

#endv

function=features(4)

End Function


sub finish() at #p0
terminate
end sub

"
o2_basic src


if len(o2_error) then
'printl o2_error
'waitkey
msgbox 0,o2_error+$cr+$cr+o2_prep src
stop
end if

o2_exec
declare function asm_support() As long at p1
declare sub finish at p0

asm_support

'msgbox 0, hex$(asm_support)

'printl hex$(Asm_support)
'printl o2_prep src
'printl o2_view src
'waitkey