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 einmal 😞

    ml-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.


Anmelden zum Antworten