ASM - Freierspeicher mit String

05/02/2012 14:43 TheCherry#1
Ich muss derzeit in ASM follgendes lösen:

- Freienspeicher finden
- In diesen die länge des Stringes schreiben
- Adresse+4 den String schreiben
- In register ECX die Speicher adresse speichern.


Ich weiß einfach nicht wie ich eine Speicheradresse finde die Frei wäre, zu dem wenn ich einen String hineinschreibe über :

std::string AccName = "test";
__asm{
MOV esi, AccName
MOV EDX, 0x06EF5150
MOV [EDX], esi
}
Steht nachher nur misst drinnen und nicht "test".

Kann mir jemand helfen?
05/02/2012 14:46 yihaaa#2
dann schau dir mal std::sting richtig an und du wirst es verstehen.

MfG
05/02/2012 14:58 xNopex#3
std::string ist eine Klasse und eine Instanz ist damit nicht nur die "reine Zeichenkette". Die wird intern wohl als char-Array oder vergleichbares gespeichert. Also versuch es mit einem char Array anstatt std::string.
05/02/2012 15:11 TheCherry#4
Quote:
Originally Posted by xNopex View Post
std::string ist eine Klasse und eine Instanz ist damit nicht nur die "reine Zeichenkette". Die wird intern wohl als char-Array oder vergleichbares gespeichert. Also versuch es mit einem char Array anstatt std::string.
Code:
char Str_[6] = "hallo";
...
MOV [ECX], Str_
kommt der Fehler: error C2415: Ungültiger Operandentyp

-----
Ich mache dies derzeit alles in nem Spiel, wo ich scheinbar eine freie speicheradresse zufällig gefunden habe.
Nun will ich den ASM teil zum testen in einem test Programm machen, doch wie räume ich mir eine "dynamische" stelle im Speicher ein?
Damit ich mit dieser arbeiten kann.
05/02/2012 15:18 Nightblizard#5
std::string ist zero-terminated. D.h. die reservierte Größe muss nicht die tatsächliche des Strings darstellen (und das tut sie in der Regel auch nicht).

Beispiel:
Code:
std::string foo = "123";
auto size = foo.capacity();
auto length = foo.length();
size beinhaltet (VS10) nun den Werten 15 und length 3.
Schauen wir uns das Ganze im Arbeitsspeicher an:

Code:
0xDEADBEEF+00: '1'
0xDEADBEEF+01: '2'
0xDEADBEEF+02: '3'
0xDEADBEEF+03: '\0'
0xDEADBEEF+04: '#' //Hier kann alles mögliche drinnen stehen
0xDEADBEEF+05: '#'
...
0xDEADBEEF+15: '#'
Wie du sehen kannst ist foo[length+1] == '\0', also NULL. Hier hört der String auf und der Rest ist, zumindest in dem Beispiel, unnötig und kann überschrieben werden.
Ich denke jetzt sollte auch klar sein wie du das machen kannst.


Quote:
Originally Posted by xNopex View Post
std::string ist eine Klasse und eine Instanz ist damit nicht nur die "reine Zeichenkette". Die wird intern wohl als char-Array oder vergleichbares gespeichert. Also versuch es mit einem char Array anstatt std::string.
Quatsch, du kannst an die Adresse des char-Arrays kommen, indem du einfach folgendes machst:
Code:
auto addr = &foo[0];



Quote:
Nun will ich den ASM teil zum testen in einem test Programm machen, doch wie räume ich mir eine "dynamische" stelle im Speicher ein?
Geht es dir nur um den Platz im Speicher? Den kannst du dir auch mit [Only registered and activated users can see links. Click Here To Register...] reservieren.
05/02/2012 16:10 xNopex#6
Ich meinte damit den Overhead der Klasse. Es wird ja nicht nur die Zeichenkette gespeichert, sondern auch Kapazität, Länge des String, und evtl. ref-counter. Dass man so an den Puffer kommt, habe ich nie bestritten.


EDIT: AFAIK ist das btw auch compilerabhängig, wie std::string implementiert wird. Also dürfte dein Code auch keine allgemein gültige Lösung sein.
05/02/2012 16:11 TheCherry#7
@Nightblizard
Vielen dank, klappt super :)
Auch wenn das game abstürzt, muss mal gucken was das ist ^^
Aber das Problem hat sich schon erledigt, danke dir :)
05/02/2012 19:39 Nightblizard#8
Quote:
Originally Posted by xNopex View Post
EDIT: AFAIK ist das btw auch compilerabhängig, wie std::string implementiert wird. Also dürfte dein Code auch keine allgemein gültige Lösung sein.
Ich habe jetzt nicht wirklich Lust im Standard nachzuschauen, aber ich bin mir sicher, dass ziemlich genau auf die Klassen und wie sie auszusehen haben eingegangen wird. Das würde ja dem Sinn der Standardisierung wiedersprechen, wenn std::string unter Windows etwas anderes ist als unter Linux.
Aber Details wie z.B. wie viel extra Speicher reserviert wird sind implementationsabhängig, weshalb ich auch in Klammern VS10 schrieb. Das sollte zeigen, dass diese Werte aus einem mit VS10 erstellten Programm stammen und bei anderen Compilern anders aussehen können.
Also prinzipiel sollte das da schon überall funktionieren (vorrausgesetzt es wird mehr Speicher als benötigt reserviert, was es eigentlich tun sollte, wenn da nicht irgendwie der Optimierer reinfingert).

Quote:
Originally Posted by xNopex View Post
Ich meinte damit den Overhead der Klasse. Es wird ja nicht nur die Zeichenkette gespeichert, sondern auch Kapazität, Länge des String, und evtl. ref-counter. Dass man so an den Puffer kommt, habe ich nie bestritten.
Oh, habe deine Aussage falsch ausgelegt. Habe mir nochmal seinen Code angesehen und jetzt wurde mir klar worauf du hinaus wolltest.
Dann vergess das zuvor von mir geschriebene einfach. ;)
05/02/2012 19:45 xNopex#9
Quote:
Aber Details wie z.B. wie viel extra Speicher reserviert wird sind implementationsabhängig, weshalb ich auch in Klammern VS10 schrieb. Das sollte zeigen, dass diese Werte aus einem mit VS10 erstellten Programm stammen und bei anderen Compilern anders aussehen können.
Exakt das habe ich gemeint. Ich meine auchmal gelesen zu haben, dass es Umsetzungsideen gibt, bei denen die Zeichenkette nicht nacheinander im Speicher abgespeichert wird, sondern wild im Speicher, wo grad Platz ist, verstreut liegt. Ka wie relevant das ist, ob das wirklich so teilweise umgesetzt wird oder ob es bei der Theorie geblieben ist.
05/02/2012 20:10 Nightblizard#10
Quote:
Originally Posted by xNopex View Post
Exakt das habe ich gemeint. Ich meine auchmal gelesen zu haben, dass es Umsetzungsideen gibt, bei denen die Zeichenkette nicht nacheinander im Speicher abgespeichert wird, sondern wild im Speicher, wo grad Platz ist, verstreut liegt. Ka wie relevant das ist, ob das wirklich so teilweise umgesetzt wird oder ob es bei der Theorie geblieben ist.
Du weißt nicht zufällig wo du das gelesen hast, oder? Das klingt spontan ersteinmal ein gutes Stück langsamer als ein char-Array zu allokieren und später einfach an einer anderen Stelle neu zu allokieren. Abgesehen vom Platzersparnis sehe ich da gerade keinen Vorteil und das würde dem Gedanken von C++ widersprechen.
05/02/2012 20:20 xNopex#11
Puh keine Ahnung. Das ist schon etwas länger her. Ein gutes Jahr bestimmt. Habs auch schon vergessen gehabt, aber das Thema hier hat mich wieder daran erinnert. Das war ein kleiner Blogeintrag soweit ich mich erinnere, in dem verschiedene "Speichermethoden" kurz vorgestellt wurden. Eine davon war diese.
05/04/2012 16:37 MrSm!th#12
Wie genau funktioniert denn da c_str()? oO
Muss dann nicht jedes Mal ein C-String daraus gebildet werden?
Ich versteh es jetzt richtig, dass du im Prinzip eine Linked List meinst?
Zumindest Insert/Replace/etc sollten da ja wesentlich schneller gehen.
05/04/2012 16:43 xNopex#13
Quote:
Wie genau funktioniert denn da c_str()? oO
Muss dann nicht jedes Mal ein C-String daraus gebildet werden?
Vllt. gibt es intelligente Lösungen von unglaublichen schlauen Menschen. Aber mir wärs dann auch nur so eingefallen, dass man für den ganzen String neuen Speicher anfordert und dann die Adresse zurückgibt. Das ist aber natürlich dann der totale Fail, weil dann der ganze Mist davor unsinnig ist. Auch der Overhead der gespeichert werden muss.. Irgendwie muss ja die Teilzeichenkette wissen, wo im Speicher die nächste Teilzeichenkette liegt. Deswegen zweifle ich ja auch daran, dass diese Art zur Implementierung irgendeine praktische Relevanz hat.
05/05/2012 20:37 Tyrar#14
^this

aber grundsätzlich kommt man bei std::string mit c_str an den pointer zur zeichen kette. und das sollte nicht von der implementierung her abhängen!