Avatar billede soreno Praktikant
09. september 2002 - 12:19 Der er 7 kommentarer og
1 løsning

_emit

jeg har i flere tilfælde stødt på følgende kode til at få fat på Read Time Stamp Counter (RDTSC) men jeg forstår det ikke:
_asm _emit 0x0F
_asm _emit 0x31

Hvad betyder _emit og hvad gør den helt eksakt ?
Er det en msvc++ only instruktion - hvad kan jeg "oversætte" den til hvis det skal virke med g++ ?
Avatar billede jpk Nybegynder
09. september 2002 - 12:33 #1
Jeg ved ikke om du har set dette...

The _emit pseudoinstruction is similar to the DB directive of MASM. You use _emit to define a single immediate byte at the current location in the current text segment. However, _emit can define only one byte at a time, and it can only define bytes in the text segment. It uses the same syntax as the INT instruction.
Avatar billede soepro Nybegynder
09. september 2002 - 13:01 #2
jpk >> Så _asm _emit 0x0F er det samme som asm { int 0x0F }; ?
Avatar billede jpk Nybegynder
09. september 2002 - 13:22 #3
glemte at skrive det er fra MSDN...

soepro >> Det vil jeg tro, men jeg er nok ikke den rigtig at spørge om det!

soreno >> Er det fordi du skal bruge en high res timer der virker cross platform eller?
Avatar billede soreno Praktikant
09. september 2002 - 13:30 #4
nej, det er i forbindelse med at beregne cpu hastighed, jeg er ved at forsøge at oversætte følgende til g++:

CString CSystemInfoDlg::CpuSpeed()
{
    int start, stop;
    int nCtr, nFreq, nCtrStop;
    QueryPerformanceFrequency((LARGE_INTEGER *)&nFreq);
    _asm _emit 0x0F
    _asm _emit 0x31
    _asm mov DWORD PTR start, eax
    _asm mov DWORD PTR [start+4], edx
    QueryPerformanceCounter((LARGE_INTEGER *)&nCtrStop);
    nCtrStop += nFreq;
    do
    {
        QueryPerformanceCounter((LARGE_INTEGER *)&nCtr);
    } while (nCtr < nCtrStop);
    _asm _emit 0x0F
    _asm _emit 0x31
    _asm mov DWORD PTR stop, eax
    _asm mov DWORD PTR [stop+4], edx
    char string[25];
    return itoa(((stop-start) / 1000000), string, 10);
}

jeg _tror_ jeg er kommet frem til at
asm ("rdtsc" : "=A" (start));

er det samme som:
_asm _emit 0x0F
_asm _emit 0x31
_asm mov DWORD PTR stop, eax
_asm mov DWORD PTR [stop+4], edx


eller er det helt hen i vejret ?
Avatar billede jpk Nybegynder
09. september 2002 - 13:58 #5
Virker RDTSC også på AMD cpu'er?
Avatar billede soepro Nybegynder
09. september 2002 - 14:06 #6
Ad 1) _emit - hvad betyder det ?
_emit svarer til ASM instruktionen DB (DataByte ?), dvs. den "kyler" den værdi du skriver efter _emit direkte ned i assembler koden, der hvor du har skrevet det. Ovenstående giver derfor følgende assembler kode:

DB  0F
DB  31
MOV  :000000, EAX
MOV  :000004, EDX

hvis vi nu antager at start-variablen ligger som den første variabel i data-segmentet. EA og ED er to af Intel CPU'ens registre - hvad der er i dem afhænger sikkert af hvad de foregående sætninger har haft gang i - alternativt indeholder de simpelthen på 0x0F og 0x31. (Det ved jeg ikke nok om assembler til at kunne afgøre.) Anyway så gemmes værdien i start og start + 4 bytes, med 32 bit integers, så var det vel meningen det skulle være stop.

Den enden gang det udføres giver for mig at se ikke megen mening - jeg ville forvente at stop + 4 bytes ville blive til nCtr.

Jeg tror personligt at der er noget galt med disse instruktioner - de giver for mig at se ingen mening. Følgende ville give mening:

_asm MOV start, eax
_asm MOV stop, edx

og senere
 
_asm MOV eax, START
_asm MOV edx, STOP

Ad 2)MVC instruktion only
Det er muligt at din g++ compiler ikke forstår _emit og dermed at den er MVC specifik. MEN ... det vigtige er at du jo laver assembler, dvs. maskinsprogsinstruktioner mod en Intel CPU - det vil jo ikke nødvendigvis fungere på en hvilken som helt Unix eller Linux maskine, hvis "hårdvaren" nedenunder ikke er Intel x86 compatibel.
Avatar billede soreno Praktikant
09. september 2002 - 16:34 #7
ad "ad 2")
det er g++'s syntaks med hensyn til asm jeg ikke kan hitte udaf.
jeg bruger g++ med windows da jeg ikke har råd til msvc++ (og ikke ønsker at bruge piratting).
Avatar billede soreno Praktikant
13. september 2002 - 10:50 #8
jeg har selv haft problemer med at finde eksempler der giver cpu speed, så derfor vil jeg lige poste et eks. der fungerer med mingw compileren - det kunne jo være andre kunne bruge det:
#include <windows.h>
#include <stdio.h>

int cpuspeed()
{
  __int64 start;
  __int64 stop;
  __int64 freq;
  __int64 count;
  __int64 countStop;
  int total;   

  QueryPerformanceFrequency((LARGE_INTEGER *) &freq);

  //Read Time Stamp Counter (RDTSC)
  //RDTSC reads a Pentium internal 64 bit register which is being incremented
  //from 0000 0000 0000 0000 at every CPU internal clockcycle.
  asm (".byte 0x0f, 0x31" : "=A" (start));

  QueryPerformanceCounter((LARGE_INTEGER *) &countStop);
  countStop += freq;

  do
  {
      QueryPerformanceCounter((LARGE_INTEGER *) &count);   
  }while(count<countStop);
 
  asm (".byte 0x0f, 0x31" : "=A" (stop));
  stop = stop - start;

  total = (int)(stop/1000000);
  return total;
}

int main(int argc, char **argv)
{
  printf("cpu speed is %iMHz", cpuspeed());

  return 0;
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester