Autor Thema: delphi, array und cpuid  (Gelesen 4485 mal)

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« am: 10. April 2009, 17:09 »
Hi,

ich mache gerade einbisschen was mit Delphi/Pascal. Ich will mittels inline-asm den Vendor-String der CPU ausgeben. So mache ich das bis jetzt:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  str: string[13];

begin
  asm
    mov eax,0
    cpuid
    mov dword ptr [str],ebx
    mov dword ptr [str+4],edx
    mov dword ptr [str+8],ecx
    mov byte ptr [str+12],0
  end;

  Writeln('Vendor-String: ' + str);
  Readln;
end.

Nur leider gibt er mir immer folgendes aus:

Zitat
Vendor-String: enuineIntel

Tjo und somit fehlt das G, da es ja GenuineIntel heißen müsste. Aber was mache ich verkehrt? Wenn ich anstatt

    mov dword ptr [str],ebx
einfach

    mov dword ptr [str+1],ebx
schreibe, dann gibt er den String net aus (vermutlich, weil sich bei [str+0] eine null befindet und er es als Ende des Zeichenstrings interpretiert. Schreibe ich aber

    mov byte ptr [str],'a'
    mov dword ptr [str+1],ebx

Dann gibt er

Zitat
Vendor-String: GenuineIntel

aus, also ohne dem a. Aber wieso? Prüft delphi ob das erste Zeichen der Zeichenkette ungleich null ist und wenn ja, dann gibt er ab dem zweiten zeichen aus, ansonsten gar nichts???? Das ist sehr mergwürdig. Kennt sich jemand von euch mit Delphi / Pascal aus?

thx

bitmaster
In the Future everyone will need OS-64!!!

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #1 am: 10. April 2009, 17:25 »
Wenn ich mich recht an eine von taljeths Aussagen erinnere, dann wird im ersten Element des Strings die Länge gespeichert.
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

MNemo

  • Beiträge: 547
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 10. April 2009, 19:06 »
Jep. Pascal Strings haben im ersten Byte die länge des Strings. Deshalb ist das
mov byte ptr [str+12],0auch nicht notwendig. Das braucht man nur bei C-Strings(null-terminiert)
„Wichtig ist nicht, besser zu sein als alle anderen. Wichtig ist, besser zu sein als du gestern warst!“

Homix

  • Beiträge: 138
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 10. April 2009, 20:02 »
Hi,
Vor allem wegen der internen Verwaltung durch den Compiler sollten Strings nie per Hand/Inline Assembler erstellt werden. Hier empfieht es sich, einfach einen null-terminierten String (PChar/Char-Array) zu verwenden und dann umwandeln zu lassen:
(Falls Delphi 2009+ verwendet wird, muss man direkt AnsiChar und PAnsiChar verwenden)

program Project1;
{$APPTYPE CONSOLE}

var str : Array[0..12] of Char;
    VendorStr : String;

begin
  asm
    mov eax,0
    cpuid
    mov dword[str],ebx
    mov dword[str+4],edx
    mov dword[str+8],ecx
    mov byte[str+12],0
  end;

  VendorStr := str;                       // Delphi sollte erkennen, dass es sich um ein Array[..] of Char fester Größe handelt und es dementsprechend umwandeln, alternativ als PChar beschreiben: "PChar(@str)"
  Writeln('Vendor-String: ',VendorStr);
  Readln;
end.

Grüße,
Stefan
« Letzte Änderung: 10. April 2009, 20:07 von stefan2005 »

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 10. April 2009, 21:45 »
Ein char-Array muß meines Wissens nicht nullterminiert sein, es ist ja schon mit fester Länge deklariert.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #5 am: 10. April 2009, 22:40 »
Ah ok vielen dank euch. Ich habe das jetzt so gemacht:

program cpuid;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  str: array[0..12] of byte;
  s: string;

begin
  asm
    mov eax,0
    cpuid
    mov dword ptr [str],ebx
    mov dword ptr [str+4],edx
    mov dword ptr [str+8],ecx
    mov byte ptr [str+12],0
  end;

  s := PAnsiChar(@str);
  Writeln('Vendor-String: ' + s);
  Readln;
end.

bitmaster
In the Future everyone will need OS-64!!!

 

Einloggen