Inline Assembler unter VC++
-
Kann mir einer an einem simplen Beispiel zeigen wie man Inline Assembler unter VC++ benützt. (z.B. Ausgabe einer Zeichenkette...)
-
ach kommt bitte wenigstens etwas
-
Also wenn du z.b. einfach die ausgabefunktion printf benutzt gehts so:
#include <stdio.h> const char output[] = "Hello, World\n"; int main(int argc, char *argv[]) { _asm { push offset output; call printf; add esp, 4; } return 0; }
Sprich: adresse von der Variable output wird auf den Stack gelegt, printf aufgerufen und dann der Stack wieder zurechtgerückt
-
hallo, wie kommst du bei add esp, 4 gerade auf 4?
-
Moin, Moin...
Mit dem Befehl add esp, 4 wird der Stack bereinigt. Bevor die Funktion printf aufgerufen wird, wird noch die Adresse der Zeichenkette(Parameter) auf den Stack gelegt. Von dort holt sich die Funktion printf die Adresse. Nachdem die Funktion ihre Aufgabe erledigt hat, muss der Parameter wieder vom Stack entfernt werden.
Da eine Adresse(Zeiger) 4 Bytes beansprucht, wird zu dem Register esp einfach 4 dazugezählt(der Stack wächst von den hohen Adressen zu den niedrigen Adressen!!!!).Ciao...
-
Nochmal Moin...
Hier noch ein Beispiel für Assembler in C:
#include <stdio.h> #include <stdlib.h> char eingabe[81]; int laenge; int main() { printf("Einen Text eingeben: "); scanf("%s", eingabe); __asm { push ebx push ecx xor eax, eax // eax löschen lea ebx, eingabe // Adresse der Zeichenkette in ebx _j1: mov cl, byte ptr [ebx] // Zeichen holen or cl, cl // Zeichen = 0 ? je _raus inc eax // Anzahl der Zeichen + 1 inc ebx // Adresse + 1 --> nächstes Zeichen jmp _j1 _raus: mov laenge, eax // Länge in die Variable schreiben pop ecx pop ebx } printf("Die Laenge der Zeichenkette: %d \n\n", laenge); system("PAUSE"); return 0; }
Ciao...
-
jawohl endlich danke leute
-
@KalEl:
Deine strlen-Funktion ist aber voll die Bremse
-
Original erstellt von <Alter Mann>:
@KalEl:
Deine strlen-Funktion ist aber voll die BremseIch weiß net ob die effizientere implementierung so einen Lehrzweck erfüllt, aber viel Spaß damit ^^ (optimiert für intelprozessoren auf 32-bit-basis)
;*** ;strlen - return the length of a null-terminated string ; ;Purpose: ; Finds the length in bytes of the given string, not including ; the final null character. ; ; Algorithm: ; int strlen (const char * str) ; { ; int length = 0; ; ; while( *str++ ) ; ++length; ; ; return( length ); ; } ; ;Entry: ; const char * str - string whose length is to be computed ; ;Exit: ; EAX = length of the string "str", exclusive of the final null byte ; ;Uses: ; EAX, ECX, EDX ; ;Exceptions: ; ;******************************************************************************* CODESEG public strlen strlen proc .FPO ( 0, 1, 0, 0, 0, 0 ) string equ [esp + 4] mov ecx,string ; ecx -> string test ecx,3 ; test if string is aligned on 32 bits je short main_loop str_misaligned: ; simple byte loop until string is aligned mov al,byte ptr [ecx] inc ecx test al,al je short byte_3 test ecx,3 jne short str_misaligned add eax,dword ptr 0 ; 5 byte nop to align label below align 16 ; should be redundant main_loop: mov eax,dword ptr [ecx] ; read 4 bytes mov edx,7efefeffh add edx,eax xor eax,-1 xor eax,edx add ecx,4 test eax,81010100h je short main_loop ; found zero byte in the loop mov eax,[ecx - 4] test al,al ; is it byte 0 je short byte_0 test ah,ah ; is it byte 1 je short byte_1 test eax,00ff0000h ; is it byte 2 je short byte_2 test eax,0ff000000h ; is it byte 3 je short byte_3 jmp short main_loop ; taken if bits 24-30 are clear and bit ; 31 is set byte_3: lea eax,[ecx - 1] mov ecx,string sub eax,ecx ret byte_2: lea eax,[ecx - 2] mov ecx,string sub eax,ecx ret byte_1: lea eax,[ecx - 3] mov ecx,string sub eax,ecx ret byte_0: lea eax,[ecx - 4] mov ecx,string sub eax,ecx ret strlen endp end
-
Moin, Moin...
@AlterMann:
Ich hatte auch nicht vor eine super-optimierte Assemblerfunktion zu präsentieren, sondern wollte nur ein Beispiel aufzeigen.
Aber vielleicht erleuchtest Du mich ja und zeigst mir genau auf, warum meine strlen-Funktion eine Bremse darstellt. Mag sein, dass ich von Deiner unendlichen Weißheit profitieren kann.
Ciao...
-
@TriPhoenix:
Wie heist das Programm? Softwarebremse? Dat bremst ja erst richtig, dann nimm lieber Kai seine func!@Kai:
Zumindest den Len-Zähler hätte man am Ende mit dem Offset subtrhieren können. Bei längeren Strings und vielen strlen macht es sich bemerkbar. Also wenn möglich, immer nur ein Increment pro schleife.
-
Moinsen...
@Alter Mann:
Ich falle in tiefer Ehrfurcht vor Deinem Wissen auf die Knie und schäme mich für meine schlichten Kenntnisse im Bereich der Assemblerprogrammierung.
Die Frage des Themas lautete: Kann mir einer an einem simplen Beispiel zeigen wie man den Inline-Assembler unter VC++ benutzt?
Es ging also nicht darum, wie man eine optimierte Assemblerroutine programmiert, sondern nur um ein Anschauungsbeispiel!!
Ciao...
-
Jo kannst wieder aufstehen
(Wollt doch nur klugschei??en und stänkern) lol
-
Original erstellt von <Alter Mann>:
**@TriPhoenix:
Wie heist das Programm? Softwarebremse? Dat bremst ja erst richtig, dann nimm lieber Kai seine func!
**Das mein lieber alter Mann kommt aus ner verbreiteten Runtime-Library, das ist net uneffizient, das nutzt die tatsache aus, 4 Byte-Blöcke zu nehmen, was der IA32 nunmal lieber macht als einzelne bytes, denn so kann man die Zahl der Speicherzugriffe senken, und die sinds die die Zeit kosten...
Deswegen ist die Routine durchaus sehr effizienz..ein Speicherzugriff ist nämlich nunmal immernoch prozessortechnisch sehr lahm