Inline Assembler in C (VC++)

Guten Tag,
ich scheiter gerade irgendwie an einem recht simplen Problem mit inline Assembler.

Code:
	LPVOID memory;


	memory = VirtualAlloc(NULL,sizeof(BYTE),MEM_COMMIT,PAGE_READWRITE);

	printf("%x",memory);
	_asm {
		PUSH EAX;
		MOV memory,90;
		POP EAX;
	}
(PUSH,POP EAX ist nur dazu da um die Stelle im Debugger zu finden)
Ich würde gerne an die Stelle "memory", die ich durch VirtualAlloc zugewiesen bekomme habe, "90" reinschreiben. Ich versteh aber nicht wirklich wie der Compiler den Code interpretiert. 90 wird in 5A umgewandelt und die Adresse für memory erscheint mir auch nicht richtig im Debugger.
Ich würde daher folgendes Wissen:
a) Wie macht man es richtig?
b) Wie macht man es ohne Assembler, so dass er auch tatsächlich 90 reinschreibt. Krieg da auch immer nur 5A reingeschrieben.

Vielen Dank.
 
Ist doch alles richtig, wenn er 5A reinschreibt...
5A ist die hexadezimale Darstellung für die dezimale 90.
 
Das man Assembler aufeinmal mit Dezimalzahlen in Visual Studio schreibt ist auch gar nicht mal so intuitiv. Also muss ich 0x90 schreiben. Danke.

Das mit dem kopieren klappt aber irgendwie immer noch nicht. Der Compiler macht daraus:
MOV DWORD PTR SS[EBP-8],90
Wobei das ganze dann auf die Adresse 000f0000 zeigt. Ist auch die Adresse die in der memory Variablen steht. Aber reinschreiben tut er trotz MOV nichts.

Hab heute irgendwie ein paar Bretter vorm Kopf.
 
Du willst eigentlich auch das hier machen:
Code:
__asm MOV EAX, DWORD PTR [memory]
__asm MOV BYTE PTR [EAX], 0x90

Memory ist eine Variable, die eine Adresse enthält. Du änderst die Adresse einfach nur zu 0x90.
Du willst aber an der Stelle, wo die vorhandene Adresse hinzeigt, eine 0x90 hinschreiben.
 
+++ATH0 hats im Prinzip schon richtig gesagt, hier gültiger Syntax:

Code:
mov [_memory], 90 ; 90 an die Speicheradr schreiben, die in memory steht
mov _memory, 90 ; 90 in der Variable memory speichern
mit _ werden globale Variablen adressiert.
 
Code:
mov [_memory], 90 ; 90 an die Speicheradr schreiben, die in memory steht
mov _memory, 90 ; 90 in der Variable memory speichern
mit _ werden globale Variablen adressiert.

Das mit den eckigen Klammern kenne ich auch noch. Scheint MSVC++ aber nicht sonderlich zu interessieren. Macht das selbe wie ohne Klammern.

@killgenerals
Nein ich wollte eben 90 Hex schreiben,deswegen war das 5A ja falsch. Hab aber auch oben geschrieben, dass ich es komisch finde das bei inline Assembler man auf einmal mit Dezimalzahlen standardmäßig schreibt anstatt mit Hex.
 
Code:
mov [_memory], 90 ; 90 an die Speicheradr schreiben, die in memory steht
mov _memory, 90 ; 90 in der Variable memory speichern

Beim Inline Assembler besteht zwischen der Klammerschreibweise und ohne kein Unterschied.
Man bedenke, dass, wenn dies funktionieren würde, eine doppelte Indirektion eines Zeigers mit einer einzigen Instruktion möglich wäre. Was ja nicht der Fall ist.
Man muss den Umweg über ein Register gehen.

Damit das klarer wir:

Angenommen memory ist, wie im Beispiel, eine lokale Variable und steht im Stack an [EBP-8].
Dann wird aus "MOV memory, 0x90" -> "MOV DWORD PTR [EBP-8], 0x00000090".
Was er aber möchte ist ein (pseudoAsm) : "MOV BYTE PTR [[EBP-8]], 0x90". Und das geht nicht. (doppelte Indirektion).

Das gilt auch für globale Variablen. Der Wert der Variable steht ja an einer Adresse, beispielsweise 0x00402000.

Also wird beispielsweise aus "MOV _memory, 0x90" -> "MOV DWORD PTR [0x00402000], 0x00000090"
Da wir schon eine Zeiger-Indirektion haben, ist keine weitere möglich.

Darüber hinaus möchte er ja nur ein Byte schreiben. Die einfachste Möglichkeit ist also, wie ich schon schrieb:
__asm MOV EAX, DWORD PTR [memory] // erste Indirektion, Zeigerwert holen
__asm MOV BYTE PTR [EAX], 0x90 // zweite Indirektion, BYTE schreiben
 
Zuletzt bearbeitet:
OK besten Dank. Also muss ich das Register nutzen,weil "memory" selbst ein Pointer ist.

Gibts eigentlich irgendwie eine Möglichkeit eine Assembler Funktion in C zu schreiben und diese dann an eine Stelle zu schreiben, wo mir garantiert wird, dass die Größe der Funktion genauso groß ist, wie nur der Opcode?

Ums mal zu verdeutlichen: Ich will eine Funktion schreiben die einfach nur:
NOP
NOP
macht und dann will ich diese Funktion einfach in einen anderen Prozess schreiben, sie darf aber auch wirklich nur die 2 Bytes für 90 und 90 gebrauchen, sprich der Compiler darf dort nichts hinzufügen, damit ich mir sicher sein kann, dass ich nur Speicher allozieren muss der 2 Bytes groß ist oder wenn ich eine andere Stelle überschreibe nicht mehr überschrieben wird als ich will. Ich könnte es jetzt auch so wie oben machen und Byte für Byte schreiben/überschreiben ist nur etwas aufwendiger und ich musste meinen Asm Code in die Opcodes übersetzen.
 
Zurück
Oben