VisualC++ Assembly mit MASM32 bauen.
-
Nabend zusammen!
Ich beschäftige mich seit kurzem wieder mit Assembler, und habe mir aus Neugier mal den Assembly-Output von kleineren Konsolenprogramme angeguckt. Den verstehe ich auch soweit (bis auf ein paar API-calls vor und nach main).
Nun wollte ich spasseshalber das ganze mit MASM32 zusammenbauen.
Als Versuchskaninchen musste ein simples Konsolen-Hello-World herhalten.
Nachdem ich aus dem VC-Verzeichnis die "listing.inc" kopiert habe, und aus dem VC-eigenen lib-verzeichnis die "oldnames.lib" ins masm32-lib-dir kopiert habe bekam ich auch eine Objektdatei.
Die kriege ich allerdings leider nicht gelinkt, und bei dem Output muss ich leider kapitulieren.Microsoft (R) Macro Assembler Version 6.14.8444 Copyright (C) Microsoft Corp 1981-1997. All rights reserved. Assembling: D:\asm-projects\hello-world\main.asm Microsoft (R) Incremental Linker Version 5.12.8078 Copyright (C) Microsoft Corp 1992-1998. All rights reserved. main.obj : error LNK2001: unresolved external symbol @__security_check_cookie@4 main.obj : error LNK2001: unresolved external symbol __imp__system main.obj : error LNK2001: unresolved external symbol __imp__printf main.obj : error LNK2001: unresolved external symbol _abs LINK : error LNK2001: unresolved external symbol _WinMainCRTStartup main.exe : fatal error LNK1120: 5 unresolved externals _ Link error
Hat jemand vielleicht eine Idee wie ich das beheben kann?
Muss ich an meinem asm-source vielleicht noch mehr einbinden was VC++ über die Linkerswitches regelt?Gruß
Tom
-
Offenbar benutzt dein Code Funktionen der VC++-Runtime. Die musst du mit einlinken. Mehr kann ich ohne den Quellcode dazu erstmal auch nicht sagen...
-
Oha...
ich habe jetzt einmal den Assembly-Output von einem Releasebuild genommen (allerdings ohne Code-Optimierung).
Jetzt assembliert er das ganze nicht einmalml-output:
Microsoft (R) Macro Assembler Version 6.14.8444 Copyright (C) Microsoft Corp 1981-1997. All rights reserved. Assembling: D:\asm-projects\hello-world\main.asm D:\asm-projects\hello-world\main.asm(14) : error A2008: syntax error : - D:\asm-projects\hello-world\main.asm(15) : error A2034: must be in segment block D:\asm-projects\hello-world\main.asm(16) : error A2008: syntax error : - D:\asm-projects\hello-world\main.asm(30) : error A2006: undefined symbol : $SG D:\asm-projects\hello-world\main.asm(36) : error A2006: undefined symbol : $SG _ Assembly Error Drücken Sie eine beliebige Taste . . .
Der eigentliche Source: (main.asm - generiert von visual c++)
; Listing generated by Microsoft (R) Optimizing Compiler Version 14.00.50727.42 TITLE d:\Projects\hello\hello\main.c .686P .XMM include listing.inc .model flat INCLUDELIB OLDNAMES EXTRN @__security_check_cookie@4:PROC EXTRN __imp__printf:PROC EXTRN __imp__system:PROC $SG-5 DB 'Hello World', 0aH, 00H ORG $+3 $SG-6 DB 'PAUSE', 00H PUBLIC _main ; Function compile flags: /Odtp ; File d:\projects\hello\hello\main.c _TEXT SEGMENT _main PROC ; 5 : { push ebp mov ebp, esp ; 6 : printf("Hello World\n"); push OFFSET $SG-5 call DWORD PTR __imp__printf add esp, 4 ; 7 : system("PAUSE"); push OFFSET $SG-6 call DWORD PTR __imp__system add esp, 4 ; 8 : } xor eax, eax pop ebp ret 0 _main ENDP _TEXT ENDS END
So wie ich das momentan verstehe hält er sich an den Variablennamen ($SG-5) auf. Das Minus will er wohl nicht. Jetzt frage ich mich allerdings warum der cl von VisualC++ damit kein Problem hat, wohl aber der ml von masm32.
Vielleicht weiss ja noch jmd Rat.
-
Oha, das interessiert mich aber auch.
Ist es damit möglich den Output nochmals von Hand zu optimieren bevor der Compiler/Linker eine Binärdatei erstellt?
-
Also nicht dass ich ein MASM-Profi waere, oder den Kram benutzen taete, aber augenscheinlich ist das, was der C++-Compiler da erstellt hat, schlicht Mist und syntaktisch falsch. KA, was der CL alles an Muell und Pseudo-Assembler schluckt - das macht es in MASM-Syntax noch lange nicht richtiger.
zB. die Fehler in Zeile 14 u. 16, bzw. 30 u. 36: Das sind AFAIK ungueltige Label-Name (bzw. hier Variablennamen).
Oder Zeile 15: Org kann - genau wie andere Daten oder Code (betrifft auch Zeilen 14, 16 und ggF. das include) - nicht ausserhalb eines Segments stehen.
Probier's mal hiermit (ungetestet) :
; Listing generated by Microsoft (R) Optimizing Compiler Version 14.00.50727.42 TITLE d:\Projects\hello\hello\main.c .686P .XMM include listing.inc .model flat INCLUDELIB OLDNAMES EXTRN @__security_check_cookie@4:PROC EXTRN __imp__printf:PROC EXTRN __imp__system:PROC _DATA SEGMENT SG_5 DB 'Hello World', 0aH, 00H ORG $+3 SG_6 DB 'PAUSE', 00H _DATA ENDS PUBLIC _main ; Function compile flags: /Odtp ; File d:\projects\hello\hello\main.c _TEXT SEGMENT _main PROC ; 5 : { push ebp mov ebp, esp ; 6 : printf("Hello World\n"); push OFFSET SG_5 call DWORD PTR __imp__printf add esp, 4 ; 7 : system("PAUSE"); push OFFSET SG_6 call DWORD PTR __imp__system add esp, 4 ; 8 : } xor eax, eax pop ebp ret 0 _main ENDP _TEXT ENDS END
@Ike: Wie meinen?
Wenn dir dein Compiler zu schlecht optimiert, such' dir einen besseren. Im fertigen Assembleroutput deines Compilers zu Optimierungszwecken rum zu pfuschen ... bringts nicht so.