Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: bitmaster am 10. April 2009, 17:09

Titel: delphi, array und cpuid
Beitrag von: bitmaster 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
Titel: Re: delphi, array und cpuid
Beitrag von: bluecode 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.
Titel: Re: delphi, array und cpuid
Beitrag von: MNemo 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)
Titel: Re: delphi, array und cpuid
Beitrag von: Homix 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
Titel: Re: delphi, array und cpuid
Beitrag von: kevin am 10. April 2009, 21:45
Ein char-Array muß meines Wissens nicht nullterminiert sein, es ist ja schon mit fester Länge deklariert.
Titel: Re: delphi, array und cpuid
Beitrag von: bitmaster 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