logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Jak napisać program w Turbo Pascalu do wykrywania typu procesora?

lucia90 11 Maj 2007 21:12 2668 15
  • #1 3874624
    lucia90
    Poziom 10  
    Posty: 46
    Ocena: 5
    witam,

    może ktoś pomoże, do napisania mam program wykrywający typ procesora i jego parametry.

    Jakieś pomysły???

    Najlepiej jak by był napisany w Turbo Pascalu, ale na inne języki też sie nie obrażę:)
  • #2 3874714
    lord_dagoth
    Poziom 25  
    Posty: 860
    Pomógł: 68
    Ocena: 6
    w tp są jakieś funkcje bądź procedury do sprawdzenia typu procesora?

    Do takiego zadanie CHYBA będzie niezbędne programowanie na niskim poziomie.
  • #3 3874751
    krzychoocpp
    VIP Zasłużony dla elektroda
    Posty: 1866
    Pomógł: 387
    Ocena: 58
    Witam, możesz skorzystać z instrukcji cpuid w asm. Do znalezienia dużo przykładów, tu jeden z lepszych:

    http://www.ka9q.net/code/cpuid/

    Pozdrawiam, Krzysztof.
  • #4 3874756
    lucia90
    Poziom 10  
    Posty: 46
    Ocena: 5
    z tego co słyszałem da się to zrobić w TP ale jak to już nie wiem,
    w ostateczności może to być w Asemblerze lub jeszcze czymś innym.
    Tylko jeśli znalazł by sie taki programik w jakimś innym języku niż TP to proszę o łopatologiczne wytłumaczenie linijka po linijce.
  • #6 3874774
    lucia90
    Poziom 10  
    Posty: 46
    Ocena: 5
    [quote="krzychoocpp"]Witam, możesz skorzystać z instrukcji cpuid w asm. Do znalezienia dużo przykładów, tu jeden z lepszych:

    http://www.ka9q.net/code/cpuid/

    przykład może i dobry tylko nie mam jak sprawdzić
    o ile wiem tar.gz to pod linuxa
  • #7 3874816
    krzychoocpp
    VIP Zasłużony dla elektroda
    Posty: 1866
    Pomógł: 387
    Ocena: 58
    Przecież tar.gz to format archiwum... Nie masz programu do rozpakowywania ? wystarczy rozpakować i skompilować, kod powinien działać pod większością systemów, dołączany jest w nim plik stdio.h, a reszta to czyste C + asm...
  • #8 3874838
    lucia90
    Poziom 10  
    Posty: 46
    Ocena: 5
    krzychoocpp napisał:
    Przecież tar.gz to format archiwum... Nie masz programu do rozpakowywania ? wystarczy rozpakować i skompilować, kod powinien działać pod większością systemów, dołączany jest w nim plik stdio.h, a reszta to czyste C + asm...



    racja jednak człowiek czasami nie myśli :)
    pozdrawiam

    i cały czas czekam na inne propozycje...
  • #9 3875261
    Xitami
    Poziom 29  
    Posty: 1130
    Pomógł: 118
    Ocena: 31
    FreePascal
    uses crt;
    { $ASMMODE INTEL}
    {$i386_intel}
    function cpuid_support : boolean;assembler;
          {
            Check if the ID-flag can be changed, if changed then CpuID is supported.
            Tested under go32v1 and Linux on c6x86 with CpuID enabled and disabled (PFV)
          }
          asm
             pushf
             pushf
             pop     eax
             mov     ebx,eax
             xor     eax,200000h
             push    eax
             popf
             pushf
             pop     eax
             popf
             and     eax,200000h
             and     ebx,200000h
             cmp     eax,ebx
             setnz   al
          end;
    
    
    function cr0 : longint;assembler;
      asm
         DB 0Fh,20h,0C0h
         { mov eax,cr0
           special registers are not allowed in the assembler
                parsers }
      end;
    
    function cpuidax(par:longword):longword; assembler; asm
      mov eax,par
      DB  00fh, 0a2h
      mov eax,eax
    end;
    function cpuidbx(par:longword):longword; assembler; asm
      mov eax,par
      DB  00fh, 0a2h
      mov eax,ebx
    end;
    function cpuidcx(par:longword):longword; assembler; asm
      mov eax,par
      DB  00fh, 0a2h
      mov eax,ecx
    end;
    function cpuiddx(par:longword):longword; assembler; asm
      mov eax,par
      DB  00fh, 0a2h
      mov eax,edx
    end;
    
    function eflags: longword;  assembler; asm
      pushf
      pop   eax
    end;
    
    CONST
      desc:array[0..31] of string=(
      // vol2a, table 3-16, page 217/750. EDX(1)
      { 0} 'Floating Point Unit On-Chip.',
      { 1} 'Virtual 8086 Mode Enhancements.',
      { 2} 'Debugging Extensions.',
      { 3} 'Page Size Extension.',
      { 4} 'Time Stamp Counter.',
      { 5} 'Model Specific Registers RDMSR and WRMSR Instructions.',
      { 6} 'Physical Address Extension.',
      { 7} 'Machine Check Exception.',
      { 8} 'CMPXCHG8B Instruction.',
      { 9} 'APIC On-Chip.',
      {10} 'Reserved',
      {11} 'SYSENTER and SYSEXIT Instructions.',
      {12} 'Memory Type Range Registers.',
      {13} 'PTE Global Bit.',
      {14} 'Machine Check Architecture.',
      {15} 'Conditional Move Instructions.',
      {16} 'Page Attribute Table.',
      {17} '36-Bit Page Size Extension.',
      {18} 'Processor Serial Number.',
      {19} 'CLFLUSH Instruction.',
      {20} 'Reserved',
      {21} 'Debug Store.',
      {22} 'Thermal Monitor and Software Controlled Clock Facilities.',
      {23} 'Intel MMX Technology.',
      {24} 'FXSAVE and FXRSTOR Instructions.',
      {25} 'SSE.',
      {26} 'SSE2.',
      {27} 'Self Snoop.',
      {28} 'Multi-Threading.',
      {29} 'Thermal Monitor.',
      {30} 'Reserved',
      {31} 'Pending Break Enable.');
    
    procedure cpuid4(par:longword);
    begin
      writeln(
        par:8, #32,
        hexstr(cpuidax(par),8), #32,
        hexstr(cpuidbx(par),8), #32,
        hexstr(cpuidcx(par),8), #32,
        hexstr(cpuiddx(par),8), #32);
    end;
    
    procedure opis;
    var x,i:longword;
    begin
      writeln('EFLAG ', hexstr(eflags, 8));
      writeln('--------.---AX--- ---BX--- ---CX--- ---DX---');
      for x:=0 to cpuidax(0) do
        cpuid4(x);
      x:=cpuidbx(0);
      while x>0 do begin
        write(char(x mod 256));
        x:=x div 256
      end;
      x:=cpuiddx(0);
      while x>0 do begin
        write(char(x mod 256));
        x:=x div 256
      end;
      x:=cpuidcx(0);
      while x>0 do begin
        write(char(x mod 256));
        x:=x div 256
      end;
      writeln; writeln;
      writeln('------- Supported -------');
      x:=cpuiddx(1);
      for i:=0 to 31 do begin
        if odd(x) then writeln(desc[i]);
        x:=x shr 1
      end;
      writeln;
      writeln('----- NOT suported ------');
      x:=cpuiddx(1);
      for i:=0 to 31 do begin
        if not odd(x) then writeln(desc[i]);
        x:=x shr 1
      end;
      writeln;
    end;
    
    function rdtsc:qword; assembler; asm
      rdtsc
    end;
    
    function GetTickCount : longint; external 'kernel32' name 'GetTickCount';
    type pqword=^qword;
    function qpc(q: pqword):boolean; external
      'kernel32' name 'QueryPerformanceCounter';
    function qpf(q: pqword):boolean; external
      'kernel32' name 'QueryPerformanceFrequency';
    
    var x,a,cp,ck:longword; p,k,s: qword;
    begin writeln;
      (*
      p:=rdtsc; writeln(p);
      opis;
      k:=rdtsc; writeln(k);
      writeln(k-p);
      p:=69;
    
      if qpf(addr(p)) then
        writeln('Frequency = ',p/1e6:0:3,' MHz, ',1/p*1e6:20:15, ' uS');
      writeln;
    
      s:=0;
      for x:=1 to 32 do begin
        p:=rdtsc(); cp:=gettickcount();
        delay(1000);
        k:=rdtsc(); ck:=gettickcount();
        s+=k-p;
        writeln(k-p:16, ' ticks, ', s div x:12, ' aver, ', ck-cp:8, ' mS (circa)');
      end;
      writeln;
      writeln((s div x) div (ck-cp):10);
      *)
      cp:=gettickcount();   while gettickcount=cp do;
      cp:=gettickcount();   while gettickcount=cp do;
    
      cp:=gettickcount();
      ck:=cp+1000;
      p:=rdtsc;
      while gettickcount()<ck do
        ;
      k:=rdtsc;
      ck:=gettickcount;
      writeln( (k-p)/1e6:0:3, ' milions ticks');
      writeln(((k-p) / (ck-cp)*1e3)/1e6 :20:6, ' MHz');
    
      //if cpuiD_support then writeln(hexstr(cr0,8))
    end.
    
  • #10 3875907
    lucia90
    Poziom 10  
    Posty: 46
    Ocena: 5
    dzięki za pomoc, zaraz przetestuje, mam nadzieje, że działa i dla
    procesorów Intela jak i AMD

    a tak w wolnej chwili może można było by jakieś opisy {komentarze}
    do niego dorzucić, tak żebym zrozumiał w pełni ten program.

    jeśli ktoś ma jakieś inne propozycje to proszę dorzucać !!!

    pozdrawiam

    Dodano po 1 [godziny] 34 [minuty]:

    dlaczego w tym programie wywala mi błąd przy
    {$i386_intel}
    17 Error Błędna Dyrektywa ???
  • #11 3876464
    Xitami
    Poziom 29  
    Posty: 1130
    Pomógł: 118
    Ocena: 31
    To jest dla FreePascala. Dla Turbo trzeba poprawić asemblerowe wstawki.
    Warto swoją drogą, zamienić Turbo na Free
  • #12 3876510
    lucia90
    Poziom 10  
    Posty: 46
    Ocena: 5
    Xitami napisał:
    To jest dla FreePascala. Dla Turbo trzeba poprawić asemblerowe wstawki.
    Warto swoją drogą, zamienić Turbo na Free


    wiem co nie zmienia faktu ze wywala błędy dotyczące tych asemblerowskich wstawek min.: unknow identifier EAX
  • #13 3884758
    Konto nie istnieje
    Konto nie istnieje  
  • #14 3885268
    lucia90
    Poziom 10  
    Posty: 46
    Ocena: 5
    tjanusz napisał:
    W drugiej linijce kodu nie powinno byc spacji pomiedzy znakami { i $

    Swoja droga ciekawe dla ktorej wersji FP bisany byl ten kod? Bo ja do tej pory nie mialem problemow z kopiwaniem rejestrow spacjalnych do rejestrow ogolnego przeznaczenia.[/code]


    to sie zgadza, ale co jest z tymi wstawkami asemblerowskimi???
  • #15 3885390
    ZeeWolf
    Poziom 28  
    Posty: 989
    Pomógł: 115
    Ocena: 58
    lucia90 napisał:

    to sie zgadza, ale co jest z tymi wstawkami asemblerowskimi???


    Parser ASM w TP "nie kojarzy" architektury 32-bitowej, tj. nie zna czegoś takiego, jak rejestry 32-bitowe i instrukcje 386.
    Najbezpieczniej jest zamiast wstawek wysilić się nieco, wklepać czysty asm, skompilować do .obj np.: Turbo Assemblerem i zrobić z tego pascalową bibliotekę (bodajże
    {$link library.obj}

    )
    - znika problem z nierozpoznawanymi instrukcjami. Ew. można używać sztuczki z "DB" ;).
  • #16 3886569
    lucia90
    Poziom 10  
    Posty: 46
    Ocena: 5
    Może jeszcze jakieś pomysły nie koniecznie w Turbo Pascalu, może być Asembler, Delphi, C++ ???

    pozdrawiam

Podsumowanie tematu

✨ Dyskusja dotyczy stworzenia programu w Turbo Pascalu do wykrywania typu procesora i jego parametrów. Wskazano, że do tego celu niezbędne jest programowanie niskopoziomowe, wykorzystujące instrukcję CPUID w asemblerze. Podano linki do przykładów kodu w C z wstawkami asm, które można rozpakować i skompilować, choć są one przeznaczone głównie pod systemy Linux. Zaproponowano również użycie Free Pascala, który obsługuje asembler w trybie Intel i pozwala na implementację funkcji sprawdzających wsparcie CPUID oraz odczytujące dane procesora. Wskazano jednak, że Turbo Pascal nie rozpoznaje 32-bitowych rejestrów i instrukcji 386, co powoduje błędy kompilacji. Sugerowano obejście tego problemu przez kompilację kodu asemblerowego do pliku .obj za pomocą Turbo Assemblera i linkowanie go z programem Pascalowym. Alternatywnie można rozważyć inne języki programowania, takie jak Delphi czy C++. Dyskusja zawiera także uwagi dotyczące składni dyrektyw kompilatora i problemów z asemblerowymi wstawkami w Turbo Pascalu.
Wygenerowane przez model językowy.
REKLAMA