Assembler in C++



  • Hallo,wie kann ich in C++ code eine Assemblerfunktion einbauen, die "Hallo Welt" ausgibt? Kann bitte jemand ein Beispiel posten?



  • mit dem Z80 geht das nicht.



  • gfenz schrieb:

    Hallo,wie kann ich in C++ code eine Assemblerfunktion einbauen, die "Hallo Welt" ausgibt? Kann bitte jemand ein Beispiel posten?

    Das hängt vom Compiler, dem Betriebssystem und nicht zuletzt dem Prozessor ab. Hier ein Beispiel für Microsoft-VC unter Windows auf Intel-i32:

    #include <windows.h>
    
    char buf[] = "Hallo Welt";
    int NumWritten;
    
    int main ( void )
    {
        __asm
        {
            push -0x0B                        ; STD_OUTPUT_HANDLE
            call DWORD PTR [GetStdHandle]
            push 0
            push OFFSET NumWritten
            push 10
            push OFFSET buf
            push eax
            call DWORD PTR [WriteFile]
        }
    
        return 0;
    }
    

    viele grüße
    ralph



  • Auf der Microsoftseite ist auch noch mal beschrieben, wie man vorgehen könnte:
    http://msdn.microsoft.com/en-us/library/t13a3526



  • Vielen Dank!

    Warum braucht man das DWORD PTR vor dem Aufruf einer Winapi Funktion?



  • gfenz schrieb:

    Warum braucht man das DWORD PTR vor dem Aufruf einer Winapi Funktion?

    Es handelt sich um einen indirekten Aufruf ( DWORD PTR [] ). Die Adresse der Winapi-Funktion wird aus einer Tabelle genommen und erst dann dahin gesprungen. Dies hängt damit zusammen, wie der Compiler Winapi-Aufrufe in die PE-Datei (EXE) einbaut.

    viele grüße
    ralph



  • gfenz schrieb:

    Hallo,wie kann ich in C++ code eine Assemblerfunktion einbauen, die "Hallo Welt" ausgibt? Kann bitte jemand ein Beispiel posten?

    __declspec(naked) BOOL WINAPI WinEcho(LPCSTR lpszOutputText, const DWORD dwLength)
    {
        __asm {
            xor EAX, EAX        
    
            cmp lpszOutputText, 0
            je fWEEnd
            cmp dwLength, 0
            je fWEEnd
    
            push EBP
            mov EBP, ESP
    
            push EDX
            push ECX
    
            push STD_OUTPUT_HANDLE
            call GetStdHandle
            cmp EAX, 0
            je fWEClean
    
            push NULL
            push NULL
            push dword ptr [EBP+0x0C]
            push dword ptr [EBP+0x08]
            push EAX
            call WriteConsole
    fWEClean:
            pop ECX
            pop EDX
    
            pop EBP
    fWEEnd:
            ret 8
        }
    }
    
    int main(int argc, char* argv[])
    {
        char* szText = "Hallo Welt\n";
    
        WinEcho(szText, strlen(szText));
    
        return 0;
    }
    

    Microsoft Visual C++ (wegen Inline Assembly naked)

    gerade ausm kopf heraus geschrieben, also ungetestet. sollte man aber schnell anpassen können. habe hier gerade keine ide zur hand. ist naked, und hoffe der compiler macht dann trotz WINAPI deklarierung keinen eigenen prolog/epilog rein, ist ja schon drinne. hf



  • danke, was bedeutet das __declspec(naked) ?



  • gfenz schrieb:

    danke, was bedeutet das __declspec(naked) ?

    hier



  • ah danke 😉



  • ausmkopfraus schrieb:

    gerade ausm kopf heraus geschrieben, also ungetestet. sollte man aber schnell anpassen können. habe hier gerade keine ide zur hand. ist naked, und hoffe der compiler macht dann trotz WINAPI deklarierung keinen eigenen prolog/epilog rein, ist ja schon drinne. hf

    Die Lösung von rkhb lässt sich mit VS2010 problemlos kompilieren.

    Die ausmkopfraus Lösung scheitert an push STD_OUTPUT_HANDLE.
    Wenn man die Stelle von rkhb übernimmt, kommt auf der Console
    leider Müll raus.

    Das ist offensichtlich besser:

    ;call WriteConsole 
         call WriteFile
    

Anmelden zum Antworten