Assembler Funktion aufrufen, Fehler



  • Hallo,

    ich nehme mir grade das Assembler "Buch" von Paul Carter vor (NASM), stoße nun beim kompilieren aber auf einige Probleme, bei denen ich selber nicht weiter komme.
    ich habe die Datei first.asm, welche eine Funktion asm_main beinhaltet in der zwei Integer-Werte addiert werden. Soweit lässt sich alles einwandfrei kompilieren...
    Nun habe ich im Visual Studio ein neues Projekt aufgemacht und habe eine Datei
    cdecl.h

    #ifndef CDECL_HEADER_FILE
    #define CDECL_HEADER_FILE
    
    #if defined(__GNUC__)
    #  define PRE_CDECL
    #  define POST_CDECL __attribute__((cdecl))
    #else
    #  define PRE_CDECL __cdecl
    #  define POST_CDECL
    #endif
    
    #endif
    

    und driver.cpp

    #include "cdecl.h"
    
    int PRE_CDECL asm_main() POST_CDECL;
    
    int main()
    {
    	int ret_status;
    	ret_status = asm_main();
    	return ret_status;
    }
    

    Folgender Fehler taucht nun auf:
    Fehler LNK2019 Verweis auf nicht aufgelöstes externes Symbol ""int __cdecl asm_main(void)" (?asm_main@@YAHXZ)" in Funktion "_main.

    Ich nehme mal an die first.obj oder asm_io.obj werden nicht gelinkt, wodurch der Compiler vermutlich denkt die Funktion asm_main() wäre deklariert aber nicht definiert... Weiß jemand wie ich das im Visual Studio realisieren kann? Würde nur ungern über die cmd kompilieren!

    LG WildChild



  • Es muss noch das name mangling mit extern "C" unterbunden werden.



  • Das habe ich schon ausprobiert, ändert aber leider nichts.



  • Guck doch mal in die generierten Objektdateien, welche Funktionen importiert und exportiert werden. Ich vermute, der Compiler lässt _asm_main importieren, also mit Unterstrich.



  • Okay, ich habe nun in die first.obj und die driver.obj geguckt in beiden taucht jeweils einmal _asm_main auf.
    Ich kenne mich mit obj Dateien nun wirklich nicht aus, habe da ehrlich gesagt noch nie reingeguckt. Daher weiß ich auch nicht, welche Stellen für den Im- oder Export stehen. Aber wie schon gesagt die einzigen Vorkommen sind mit Unterstrich vor dem asm.
    Wenn ich nun in meiner driver.cpp den Unterstrich hinzufüge ändert das aber leider auch nichts...



  • Das scheint ja jetzt eher ein IDE als ein C++ Problem zu sein ...

    Werden die asm aus der IDE heraus übersetzt?
    Was hast du unternommen, um die obj Datei zu linken?



  • Wenn in driver _asm_main importiert wird, hänge an den Symbolnamen asm_main in der asm-Datei auch noch nen Unterstrich dran.



  • 1. asm_main muss in der Cpp mit extern "C" deklariert sein
    2. deine asm_main muss in der asm-File ein _-Präfix haben (da der msvc das vor jede C-Funktion klatscht)
    3. deine Funktion muss in der asm-File als global markiert sein

    Wenn das alles nicht hilft, musst du mal mehr Infos schicken (nasm-Commandline, asm-Code, ggf. noch den dumpbin-Output und evtl. noch deine link-Commandline)



  • JulianH schrieb:

    1. asm_main muss in der Cpp mit extern "C" deklariert sein
    2. deine asm_main muss in der asm-File ein _-Präfix haben (da der msvc das vor jede C-Funktion klatscht)
    3. deine Funktion muss in der asm-File als global markiert sein

    Wenn das alles nicht hilft, musst du mal mehr Infos schicken (nasm-Commandline, asm-Code, ggf. noch den dumpbin-Output und evtl. noch deine link-Commandline)

    Die punkte 1-3 sind zutreffend. die asm habe ich wie folgt kompiliert: nasm -f win32 first.asm
    Die obj-Files anschließend in meinen VS Projektordner und soweit ich weiß sollte das Visual Studio sich die selber ziehen. Oder muss ich diese extra linken? Dann liegt es nämlich daran.



  • WildChild schrieb:

    Oder muss ich diese extra linken? Dann liegt es nämlich daran.

    Ja!



  • Th69 schrieb:

    WildChild schrieb:

    Oder muss ich diese extra linken? Dann liegt es nämlich daran.

    Ja!

    Und wo linkt man im Visual Studio obj-Files?



  • Ich hab die obj-Files einfach zum Projekt hinzugefügt laut google ist das genau das was ich suche...
    Die bisherige Fehlermeldung verschwindet dadurch auch, jedoch erscheinen nun Neue.
    Nicht aufgelöstes externes Symbol _scanf und _printf in asm_io.obj



  • Ich vermute mal, die Funktionsnamem der crt sind auch durch die Mangel gedreht worden, daher erstelle im C++-Modul eine 'myprintf' oder so, die dann vom asm-modul aufgerufen wird und diese das printf der crt aufruft (bzw vsprintf). Nicht vergessen, extern C drumherum zu wickeln.



  • Also liegts an der asm_io?
    Ich kann bisher so gut wie gar kein Assembler, habe erst heute mit dem Buch angefangen. Und in diesem Buch wird immer auf die vom Autor mitgelieferte asm_io zurückgegriffen... Also ich hab keine Ahnung wie ich nun im Assembler Code auf eine in C geschriebene myprintf zugreifen kann....
    Vielleicht kann mir ja auch jemand ein gutes Tutorial oder Buch sagen bei dem ich nicht auf irgendwelche mitgelieferten (und möglicherweise veralteten oder fehlerhaften) libraries o. ä. zugreifen muss?
    Mir geht es eigentlich im Speziellen darum, inline Assembler oder durch solche Treiberfunktionen geladene asm-Files zu schreiben. Keinen reinen Assembler Code. Daher wäre die asm_io ohnehin unnötig. Eingabe/Ausgabe würde für mich eh über C/C++ gemacht werden.



  • Was sind "solche Treiberfunktionen" 😕

    Was inline Assembler angeht...
    Inline Assembler ist compilerspezifisch (d.h. nicht portierbar). Und Visual Studio unterstützt Inline Assembler nur für x86, nicht für ARM und auch nicht für x64. Aber davon abgesehen, für Visual C++ sollten sich super-einfach super-einfache Beispiele ergoogeln lassen.

    Bzw. fang mal hier an und lies dich durch die verschiedenen Abschnitte/Themen:
    https://msdn.microsoft.com/en-us/library/4ks26t93.aspx

    WildChild schrieb:

    Also liegts an der asm_io?
    (...)
    Daher wäre die asm_io ohnehin unnötig. Eingabe/Ausgabe würde für mich eh über C/C++ gemacht werden.

    Dann link das asm_io Object einfach nicht dazu. Sollte reichen.


Log in to reply