Ram Speicher auführen
-
Guten Abend ich hatte mal eine Grundlegende Frage zu Assembler. Ich habe unter fasm eine Funktion geschreiben in asm und habe die nun vom Compiler zu einer Objekt Datei assemblieren lassen. Diese Datei lade ich mithilfe einer höheren Programmiersprache(C++) in den Ram. Nun kommt das Problem die Funktion wird richtig ausgeführt, außerdem wird auch der Rücksprung richtig ausgeführt leider tut die Funktion nicht was sie tun soll..
Die Funktion bekommt die Addresse einer Variable, der Wert dieser Variablen soll in der Funktion geändert werden. Ich poste jetzt nur den asm code auf nachfrage kann ich auch den C++ Code posten._MyFunc: push ebp mov ebp,esp mov eax,[ebp+8] mov ebx,dword[100h] mov [eax],ebx pop ebp ret
Falls ein Fehler im Assembler Code ist bitte posten^^
-
SpR schrieb:
mov ebx,dword[100h]
Vielleicht wolltest du die Eckigen Klammern weglassen? - 100h ist keine gültige Adresse.
Ansonsten: Stimmen die calling conventions überein (c-call)?
-
Ja die calling Conventions stimmen überein , und ich mache das hier nur weil mir mein Compiler bei dem hier nen Fehler ausspuckt:
mov ebx,100h
Und die addresse der Variablen liegt auf dem stack , die addresse der Variablen hole ich ja so ab:
mov eax,[ebp+8]
ich will ja ebx in den Wert von eax schreiben deswegen glaube ich schon das es nicht wichtig ist ob dies ne gültige addresse ist: 100h
-
Ja, aber was steht denn so tolles bei Adresse 100h? Normalerweise schreibt man doch eher
mov ebx,[meineErsatzVariable]
oder so.
(oder eben über Paramenterangabe (noch ne Variable) (ebp + 12) wenn man von einem C Programm Variablen übergibt.
Dass die eckigen Klammern den "Inhalt" bzw. den Wert der Variablen meinen, ist hoffentlich klar?Und mov ebx,100h sollte keine Fehlermeldung bringen, wieso das denn?
Womöglich stimmt etwas weiter oben im Programm nicht, der Zeiger, der nach eax geladen wird ist, ist vielleicht nicht so passend, sieht zumindest danach aus.
-
SpR schrieb:
ich will ja ebx in den Wert von eax schreiben deswegen glaube ich schon das es nicht wichtig ist ob dies ne gültige addresse ist: 100h
Oh doch!
Also, ich habe das Ganze unter Windows getestet, und es funktioniert. Sowohl "mov ebx, 100h" als auch "mov ebx, dword [100h]" werden von FASM anstandslos kompiliert, letzteres produziert beim Ausführen unter Windows allerdings einen Absturz, da der Speicher bei 0x00000100 nicht zum Lesen freigegeben ist. Ersteres funktioniert wie gewünscht. Allerdings bereitet mir ein bisschen Sorge, dass der auf dem Stack liegende Wert über DS geändert wird.
Deine Angaben sind einigermaßen verwirrend:
- Welches Betriebssystem, welcher Compiler?
- Was zum Donnerwetter heißt "Diese Datei lade ich ... in den Ram"?
- Woher weißt Du, dass die Funktion und der Rücksprung richtig ausgeführt werden?
- "nen Fehler" ist unter Umständen etwas ungenau.
- Wenigstens Deklaration und Aufruf der Funktion hättest Du mitteilen können.
viele grüße
ralph
-
Hmm also ich habe asm größenteils über inline Assembler geübt , da ich Windows 7 habe und daher die Hardware Interrupts nicht mehr möglich sind benutze ich Assembler nur zum optimieren einiger C++ Funktionen. Ich rufe die Funktion wie Folgt auf( im C++ Programm mit inline asm):
lea eax,MeineVariableDerenWertGeändertWerdenSoll push eax call MeineFunktion
So rufe ich die Funktion im Programm auf!
_MyFunc: push ebp mov ebp,esp mov eax,[ebp+8] mov ebx,dword[100h] mov [eax],ebx pop ebp ret
Der Plan war in eax die Addresse der Variablen zu "bekommen". Nun wollte ich da dies nicht geht:
_MyFunc: push ebp mov ebp,esp mov eax,[ebp+8] mov [eax],100h pop ebp ret
Das einzige was diese Funktion machen soll ist den Wert der Variablen deren Addresse ich übergeben habe zu verändern
-
Dies macht Fasm aus meiner Funbktion:
00030000 55 push ebp
00030001 66 89 E5 mov bp,sp
00030004 67 66 8B 45 08 mov ax,word ptr [di+8]
00030009 66 BB 64 00 mov bx,64h
0003000D 00 00 add byte ptr [eax],al
0003000F 67 66 01 18 add word ptr [bx+si],bx
00030013 66 5D pop bp
00030015 C3 ret
-
Das hier ist das Problem:
00030000 89 E8 mov eax,ebp 00030002 66 50 push ax
In eax sthet jz die richtige Größe also die Größe von ebp allerdings macht fasm ax daraus... in ax steht nur ein Teil der Addresse und da ist das Problem..
Hätte einer von euch ne Idee , das fasm den Code nicht entfremdet?
-
Also eig. ist das einzige was ich brauche , das nasm den Code nicht verändert. Wenn ich die Funktion in inline Assembler von Visual Studio 2008 schreibe wird der Asm code richtig übersetzt nur nasm macht aus
push eax
immer
push ax
<.<
-
SpR schrieb:
nur nasm macht aus
push eax
immer
push ax
<.<
entweder verwendest du den falschen dissassembler oder du bedienst ihn falsch.
-
Durchausmöglich , merkwürdig ist nur , das der von Visul Atudio inline asm erstellte code läuft un der von nasm nicht^^
-
SpR schrieb:
Durchausmöglich , merkwürdig ist nur , das der von Visul Atudio inline asm erstellte code läuft un der von nasm nicht^^
NASM oder FASM? Das sind zwei verschiedene Assembler! Aber der von Dir Dir gepostete Problemcode gehört doch zum Inline-Assembler von VC++.
Ich kann Dein Problem hier immer noch nicht reproduzieren. Versuch mal folgende Kombination:
format MS COFF public _MyFunc SECTION '.text' code readable executable _MyFunc: push ebp mov ebp, esp mov eax, [ebp+8] mov ebx, 1000 add [eax], ebx pop ebp ret
#include <iostream> using namespace std; extern "C" void MyFunc(int*); int main() { int VarToChange = 1000; cout << "VarToChange=" << VarToChange << endl; MyFunc (&VarToChange); cout << "VarToChange=" << VarToChange << endl; _asm { lea eax, VarToChange push eax call MyFunc add esp, 4 } cout << "VarToChange=" << VarToChange << endl; return 0; }
Diese Kombination sollte klappen. Die FASM-Funktion addiert immer 1000 zur übergebenen Variable. Beachte, dass man bei der C-Calling-Convention den Stack selbst aufräumen muss (Zeile 18 der C++-Datei).
viele grüße
ralph
-
SpR schrieb:
push ebp
mov bp,sp
mov ax,word ptr [di+8]
mov bx,64h
add byte ptr [eax],al
add word ptr [bx+si],bx
pop bp
retSollte möglichst was korrumpieren.
Um aber dir alles sagen zu können müsstest du schon mal
dein komplettes Disassembly posten.
Ausserdem 16Bit mit 32Bit kram zu mischen ist auch nicht so toll.Warum benutzt du nicht MASM32 ?
Auch unter Win7 kann man Software Interrupts benutzen,
sofern du dich im Kernelmodus "befindest".PS: Du kannst auch direkt IASM verwenden:
__declspec(naked) BLA CALLINGBLA name(BLUB) { __asm { ret } }
-
Warum benutzt du nicht die HL-Syntax von MASM? Ist doch viel bequemer.
Merke: ESI, EDI, EBX müssen vor Ende der Subfunktion wieder auf die Werte vor dem Aufruf zurückgestellt werden (Push/Pop)
MASM-Beispiel: \MASM32\datetime\CopyDateTime.asm.486 ; create 32 bit code .model flat ; 32 bit memory model option casemap :none ; case sensitive MyFunc PROTO C :DWORD myval equ 1234 MyFunc proc C uses ebx edi esi myvar:DWORD mov eax,myvar mov [dword ptr eax],myval ;oder: ; add dword ptr [eax],myval ;oder: ; mov ebx,myval ; sub dword ptr [eax],ebx ret MyFunc endp end
-
Tut mir leid wegen dem pop ebp und pop ebp habe ich leider vergessen ich benutze nasm als Assembler. Das Problem hat sich schon geklärt. Vielen Dank für die Antworten konnte in diesem Fall viel lernen.