Jump to content
  • Advertisement
Sign in to follow this  
lonewolff

Recompile VS.net C++ generated ASM file?

This topic is 853 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Guys,
 
I have made the simplest of 'hello world' applications in C++ to take a look at the generated ASM output
 
C++ listing
 
#include<iostream>

int main()
{
	system("PAUSE");
	return 0;
}
 
 
Visual Studio is showing that the resultant ASM is as follows
 
; Listing generated by Microsoft (R) Optimizing Compiler Version 19.00.23026.0 

	TITLE	main.cpp
	.686P
	.XMM
	include listing.inc
	.model	flat

INCLUDELIB OLDNAMES

PUBLIC	??_C@_05DIAHPDGL@PAUSE?$AA@			; `string'
EXTRN	__imp__system:PROC
EXTRN	@__security_check_cookie@4:PROC
;	COMDAT ??_C@_05DIAHPDGL@PAUSE?$AA@
CONST	SEGMENT
??_C@_05DIAHPDGL@PAUSE?$AA@ DB 'PAUSE', 00H		; `string'
CONST	ENDS
PUBLIC	_main
; Function compile flags: /Ogtp
;	COMDAT _main
_TEXT	SEGMENT
_main	PROC						; COMDAT
; Line 5
	push	OFFSET ??_C@_05DIAHPDGL@PAUSE?$AA@
	call	DWORD PTR __imp__system
	add	esp, 4
; Line 6
	xor	eax, eax
; Line 7
	ret	0
_main	ENDP
_TEXT	ENDS
END

Is it possible to re-compile the ASM file from the command line back in to the exe?
 
 
I can get pretty close if I modify the source code (essentially adding all of the libs that are referenced in the linker section of the VS projected properties), but I keep getting a linker error
 
.686P
.XMM

.model	flat

INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\shell32.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\kernel32.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\user32.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\gdi32.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\winspool.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\comdlg32.lib" 
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\advapi32.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\shell32.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\ole32.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\oleaut32.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\uuid.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\odbc32.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\odbccp32.lib"

PUBLIC	system_pause			; `string'
EXTRN	__imp__system:PROC

CONST	SEGMENT
system_pause	DB 'PAUSE', 00H		; `string'
CONST	ENDS

_TEXT	SEGMENT
_mainCRTStartup	PROC
; Line 5
	push	OFFSET system_pause
	call	DWORD PTR __imp__system
	add	esp, 4
; Line 6
	xor	eax, eax
; Line 7
	ret	0
_mainCRTStartup	ENDP
_TEXT	ENDS
END

 

source.obj : error LNK2001: unresolved external symbol __imp__system
source.exe : fatal error LNK1120: 1 unresolved externals


So, I can't work out which library that the linker is looking for.

This is all just for personal learning purposes but any advice would be greatly appreciated smile.png

Share this post


Link to post
Share on other sites
Advertisement
You forgot to link in the C runtime perhaps?

This contains all of the basic C++ routines that are intrinsic to C++ but not assembler, including system initialisation before main() and shutdown after exit(), e.g. initialisation of static objects and destructors.

Have you checked for this?

Share this post


Link to post
Share on other sites
So try linking libc as well you mean?

So far I have only tried linking what was in the linker properties box in VS.net. So, it seems that VS must do more behind the scenes that it lets on.

Share this post


Link to post
Share on other sites

system is implemented in libc, so yes, I would expect you to have to link with that too.

 

I havn't used VS.net, no idea why it wouldn't list libc in its linker properties, since it obviously needs it.

Maybe some kind of misguided "simplification"? 

Edited by Olof Hedman

Share this post


Link to post
Share on other sites
Hmmm, seems like a dead end. Doesn't seem there is a 'libc' as such in VS.net. Maybe it hides under an alternate name.

Share this post


Link to post
Share on other sites
It is called the visual c++ runtime/redistributable and it can be referenced externally via a dll or statically linked into your executable.

Share this post


Link to post
Share on other sites

Hmmm, seems like a dead end. Doesn't seem there is a 'libc' as such in VS.net. Maybe it hides under an alternate name.

 
Depending on your version of Visual Studio, you may have to use ucrtbase.lib and libvcruntime.lib instead of libc(mt):
 
https://msdn.microsoft.com/en-us/library/bb531344.aspx#Anchor_1


Thanks dude, this got me on the right track.

I am using the Windows SDK v10 so I had to include the following

INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86\libucrt.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86\ucrt.lib"
Seems that the 'Universal CRT' is new way that Microsoft is doing things. With the earlier SDK's you'd probably need to link ucrtbase.lib and libvcruntime.lib as mentioned above.

Share this post


Link to post
Share on other sites
So I have now managed to successfully created an exe file reconstructed by the ASM file alone cool.png
 
For anyone who might be interested, this is what I had to do in the end.
 
; Listing generated by Microsoft (R) Optimizing Compiler Version 19.00.23026.0 

	TITLE	PathToProject
	.686P
	.XMM
	include listing.inc ; Located in "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include"
	.model	flat

INCLUDELIB OLDNAMES ; Located in C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib

; These were listed in the VS linker project properties 
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\kernel32.lib" 
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\user32.lib" 
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\gdi32.lib" 
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\winspool.lib" 
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\comdlg32.lib" 
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\advapi32.lib" 
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\shell32.lib" 
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\ole32.lib" 
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\oleaut32.lib" 
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\uuid.lib" 
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\odbc32.lib" 
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\um\x86\odbccp32.lib"

; **** These are required but are not listed in the project properties - Why is this? How does VS know to include them? ****
INCLUDELIB "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\libcmt.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86\libucrt.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86\ucrt.lib"


PUBLIC	??_C@_05DIAHPDGL@PAUSE?$AA@			; `string'
EXTRN	__imp__system:PROC
;EXTRN	@__security_check_cookie@4:PROC
;	COMDAT ??_C@_05DIAHPDGL@PAUSE?$AA@
CONST	SEGMENT
??_C@_05DIAHPDGL@PAUSE?$AA@ DB 'PAUSE', 00H		; `string'
CONST	ENDS
PUBLIC	_main
; Function compile flags: /Ogtp
;	COMDAT _main
_TEXT	SEGMENT
_main	PROC						; COMDAT
; File c:\users\user\documents\visual studio 2015\projects\playing_with_optimisation\playing_with_optimisation\main.cpp
; Line 5
	push	OFFSET ??_C@_05DIAHPDGL@PAUSE?$AA@
	call	DWORD PTR __imp__system
	add	esp, 4
; Line 6
	xor	eax, eax
; Line 7
	ret	0
_main	ENDP
_TEXT	ENDS
END
I built and linked it like this (probably not optimal, but it works with the example)

Ml.exe /c /coff source.asm
Link.exe /SUBSYSTEM:CONSOLE source.obj



I'm still not sure how VS.net 2015 knows how to reference these libraries as I can't see any trace of these in the VS linker pages.

INCLUDELIB "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\libcmt.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86\libucrt.lib"
INCLUDELIB "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.10240.0\ucrt\x86\ucrt.lib"
Apart from that, the mystery is solved as to how to reconstruct from an ASM file.

I'm interested to see how ASM handles a basic 'class'. That will probably be my next experiment.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!