Inline Assembler Problem
-
Ok ich muss number zu dem element addieren zu dem der pointer *element zeigt. *element und integer kommen von C code. Hab absolut keine Ahnung wie ich das machen kann. Danke schon mal im voraus fuer die Hilfe.
__declspec(naked) list*
ADD_CONSTANT_TO_LIST_ELEMENT (list *element, int number)
{
__asm {
push ebx
push ecx
mov ebx,dword ptr[esp+12]
mov ecx,dword ptr[esp+16]cmp ebx,0
je END
jmp ADDITIONADDITION:
//code goes herepop ecx
pop ebx
retEND:
mov eax,ebx
pop ecx
pop ebx
ret}
}
-
_asm mov eax, element _asm add [eax], number
das reicht aus
-
danke fuer die Hilfe leider muss ich alle Werte vom Stack ziehn habs aber zum laufen gebracht hier ist der code:
ADD_CONSTANT_TO_LIST_ELEMENT (list *element, int number)
{
__asm {
push ebx
push edx
mov ebx,dword ptr[esp+12]
mov edx,dword ptr[esp+16]
cmp ebx,0
je END
mov ecx,dword ptr[ebx+4]
add ecx,edx
jmp END2END:
pop edx
pop ebx
retEND2:
mov dword ptr[ebx+4],ecx
pop edx
pop ebx
ret}
-
ecx sollte vermutlich auch wiederhergestellt werden.
die defintion deiner function hat einen rueckgabe-wert "list*" der durch "__declspec(naked) " in eax erwartet wird.
den "end:"-block kannst du einsparen indem du gleich zu den unteren pops springst, womit das "jmp end2" entfaellt.
-
es genügt ebx zu sichern. aus der syntax schlussfolgere ich mal, dass es sich um den microsoft compiler handelt. in dem falle sind eax, ecx und edx 'volatile', dürfen also verändert werden. daher dürfte es am sinnvolsten sein, gleich nur eax,ecx und edx zu verwenden - das geht hier ja problemlos - und das sichern von registern ganz zu unterlassen. andererseits ist das ja wohl ohnehin eine übungsaufgabe. die definition von list würde mich allerdings intressieren - wenn das nicht gerade ein typedef auf int ist, ist der code, so wie er jetzt ist, vermutlich eher sinnlos.
-
typedef struct list {
struct list *next;
int value;
} list;das ist die list defenition
Ich hab aber noch eine weiter frage . Ich muss eine Daten Struktur veraendern (Liste). Muss das element int valu in a_list finden und dann loeschen. Mein Problem ist das ich mit dem Befehl "mov eax,dword ptr[esi+ebx*4]" zwar die adresse der einzelnen Nodes bekomme aber nicht den Wert. Hat jemand von euch ne Ahnung wie ich den Wert bekommen kann fuer die einzelnen addressen? Vielen Dank
_declspec(naked) list *
DELETE_FROM_LIST (list * a_list, int value)
{__asm {
mov esi,dword ptr[esp+4]
mov ecx,10
xor ebx,ebxNEXT:
mov eax,dword ptr[esi+ebx*4]
inc ebx
jmp NEXT
ret}
}
-
du hast ja die adresse (pointer) der liste in einem register, ueber dieses register kannst du auf die zwei elemente der struktur zugreifen:
mov eax,[esp+4] // value mov ebx,[esp+0] // adresse der naechsten node
ueber das register (hier ebx) in die du die neue adresse geladen hast, kannst du dann das naechste element ansprechen:
mov eax,[ebx+4] // value
usw...
zum entfernen des aktuellen elements musst du den next-zeiger vom vorherigen (sofern existent) auf das naechste zeigen lassen und den speicher des aktuellen freigeben.
-
jochen06 schrieb:
typedef struct list {
struct list *next;
int value;
} list;so kommen wir der sache schon näher. ich hab mir mal die freiheit genommen, die erste funktion und eine find funktion zu implementieren:
typedef struct list { struct list *next; int value; } list; __declspec(naked) list* ADD_CONSTANT_TO_LIST_ELEMENT(list *element, int value) { __asm { mov eax, [ esp + 4 ] // element mov edx, [ esp + 8 ] // value test eax, eax jz exit_ add list::value[ eax ], edx // alternative syntax: add [ eax ]list.value, edx exit_: ret } } __declspec(naked) list* FIND(list* a_list, int value) { __asm { mov eax, [ esp + 4 ] // a_list mov edx, [ esp + 8 ] // value jmp start_ loop_: mov eax, list::next[ eax ] start_: test eax, eax jz exit_ cmp list::value[ eax ], edx jne loop_ exit_: ret } }
die zeile wo ich eine alternative syntax angegeben habe, ist das intressante daran. im prinzip wollen wir einen ausdruck [eax+offsetof(list,value)] (nur ist offsetof ein C macro, das wir hier nat. nicht einsetzen können) - und es gibt auch ein paar syntaktische varianten, die der compiler hier akzetiert. die beiden, die ich oben gezeigt habe, haben allerdings den vorteil, dass sie auch der intel compiler für windows versteht - falls du jemals in verlegenheit gerätst, diesen benutzen zu wollen. die tradiotionelle methode der art
(list ptr [eax]).value
wie man sie in standalone assembler verwenden würde, scheitert an einigen beschränkungen des inline assemblers.