Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet 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:
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
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
-
Wenn ich mich recht an eine von taljeths Aussagen erinnere, dann wird im ersten Element des Strings die Länge gespeichert.
-
Jep. Pascal Strings haben im ersten Byte die länge des Strings. Deshalb ist das
mov byte ptr [str+12],0
auch nicht notwendig. Das braucht man nur bei C-Strings(null-terminiert)
-
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
-
Ein char-Array muß meines Wissens nicht nullterminiert sein, es ist ja schon mit fester Länge deklariert.
-
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