I am trying to create a helloworld program using only masm and not masm32 libs. Here is the code snippet:
.386
.model flat, stdcall
option casemap :none
extrn MessageBox : PROC
extrn ExitProcess : PROC
.data
HelloWorld db "Hello There!", 0
.code
start:
lea eax, HelloWorld
mov ebx, 0
push ebx
push eax
push eax
push ebx
call MessageBox
push ebx
call ExitProcess
end start
I am able to assemble this using masm:
c:\masm32\code>ml /c /coff demo.asm
Microsoft (R) Macro Assembler Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.
Assembling: demo.asm
However, I am unable to link it:
c:\masm32\code>link /subsystem:windows /defaultlib:kernel32.lib /defaultlib:user
32.lib demo.obj
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.
demo.obj : error LNK2001: unresolved external symbol _MessageBox
demo.obj : error LNK2001: unresolved external symbol _ExitProcess
demo.exe : fatal error LNK1120: 2 unresolved externals
I am including the libs during linking, so not sure why it still says unresolved symbols?
UPDATE:
c:\masm32\code>link /subsystem:windows /defaultlib:kernel32.lib /defaultlib:user
32.lib demo.obj
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.
demo.obj : error LNK2001: unresolved external symbol _MessageBox#16
demo.exe : fatal error LNK1120: 1 unresolved externals
UPDATE 2: Final working code!
.386
.model flat, stdcall
option casemap :none
extrn MessageBoxA#16 : PROC
extrn ExitProcess#4 : PROC
.data
HelloWorld db "Hello There!", 0
.code
start:
lea eax, HelloWorld
mov ebx, 0
push ebx
push eax
push eax
push ebx
call MessageBoxA#16
push ebx
call ExitProcess#4
end start
The correct function names are MessageBoxA#16 and ExitProcess#4.
Almost all Win32 API functions are stdcall, so their names are decorated with an # sign, followed by the number of bytes taken up by their parameters.
Additionally, when a Win32 function takes a string, there are two variants: one that takes an ANSI string (name ends in A) and one that takes a Unicode string (name ends in W). You're supplying an ANSI string, so you want the A version.
When you're not programming in assembly the compiler takes care of these points for you.
Try adding this before .data segment:
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
Related
So I'm currently trying to call the exported functions of a dll inside my assembly file.
The DLL is in the same directory as my asm program, I don't have the .lib file.
Here is my code:
EXTERN __imp__CreateCompressor#12:PROC
EXTERN __imp__Compress#24:PROC
EXTERN __imp__CloseCompressor#4:PROC
.code
START:
push 2 ;COMPRESS_ALGORITHM_MSZIP
push 0
push OFFSET hCompress
call __imp__CreateCompressor#12
push 0 ;CompressedDataSize
push DWORD ptr [DataSize] ;CompressedBufferSize
push eax ;CompressedBuffer
push DWORD ptr [DataSize]
push DWORD ptr [pBuf3]
push DWORD ptr [hCompress]
call __imp__Compress#24
push DWORD ptr [hCompress]
call __imp__CloseCompressor#4
END START
However I get the errors:
file.obj : error LNK2001: unresolved external symbol ___imp__CreateCompressor#12
file.obj : error LNK2001: unresolved external symbol ___imp__Compress#24
file.obj : error LNK2001: unresolved external symbol ___imp__CloseCompressor#4
file.exe : fatal error LNK1120: 3 unresolved externals
I'm assembling it like so:
ml file.asm /link /subsystem:console /entry:START
Any ideas?
You must use LoadLibrary() and GetProcAddress() functions to load the library and get the address from the function you want to call.
To enable Load-Time Dynamic Linking the linker needs an import library.
Without an import library you're going to have to use Run-Time Dynamic Linking.
Alternatively, you can generate an import library yourself. The easiest way to do so is to author an appropriate Module-Definition (.Def) File and have the Microsoft Librarian Manager (LIB.exe) generate an import library.
Writing a solution in Windows using Visual Studio 2013 C++ and trying to get the _penter and _pexit hooks working.
Getting error LNK2001: unresolved external symbol _pexit and error LNK2001: unresolved external symbol _penter for all my project files when I compile it with /Gh and /GH. I have a solution with two projects - one my main project compiled with /GH and /Gh and another DLL project which defines _penter and _pexit in an assembly file(wrote a seperate assembly file for it since my application is x64).
If I have another symbol(a different function in the DLL), that is being seen and I am able to call it from the other project and it works properly as expected, but when I compile with /GH and /Gh options its not finding the definitions for _penter and _pexit. Not able to find why this happens.
Also, if I try to write the _penter and _pexit in the cpp file itself, it gets exposed and the other project is able to see it. But I cant write inline assembly in x64, so I've written it in a seperate asm file but that doesnt get exposed.
Also, I tried writing a def file as follows,
LIBRARY EXTLIB
EXPORTS _penter
EXPORTS _pexit
and point my main project to it, it gives me these two errors,
1>------ Build started: Project: MyProj, Configuration: Release x64 ------
1>Definitions.def : error LNK2001: unresolved external symbol _penter
1>Definitions.def : error LNK2001: unresolved external symbol _pexit
1>..\..\build\MyProj.lib : fatal error LNK1120: 2 unresolved externals
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========
when I dont give the def file, the errors are like,
1>Reality.obj : error LNK2001: unresolved external symbol _pexit
1>Reality.obj : error LNK2001: unresolved external symbol _pexit
...
for all my files in the project.
What am I doing wrong? How do I make my project see the definition for _penter and _pexit?
EDIT:
extern entry:Proc
extern exit:Proc
PUBLIC _penter
PUBLIC _pexit
EXPORTS _penter
EXPORTS _penter
.code
PUSHREGS macro
push rax
push rcx
push rdx
push r8
push r9
push r10
push r11
endm
POPREGS macro
pop r11
pop r10
pop r9
pop r8
pop rdx
pop rcx
pop rax
endm
_penter proc
push rax
lahf
PUSHREGS
sub rsp, 8+16
movdqu xmmword ptr[rsp], xmm0
sub rsp ,8
sub rsp,28h
mov rcx,rsp
mov rcx,qword ptr[rcx+136]
call entry
add rsp,28h
add rsp, 8
movdqu xmm0, xmmword ptr[rsp]
add rsp, 8+ 16
POPREGS
sahf
pop rax
ret
_penter endp
_pexit proc
push rax
lahf
PUSHREGS
sub rsp, 8+16
movdqu xmmword ptr[rsp], xmm0
sub rsp ,8
sub rsp,28h
mov rcx,rsp
mov rcx,qword ptr[rcx+136]
call exit
add rsp,28h
add rsp, 8
movdqu xmm0, xmmword ptr[rsp]
add rsp, 8+ 16
POPREGS
sahf
pop rax
ret
_pexit endp
end
.386
.model flat, c
.stack 100 h
.data
num1 sdword ?
num2 sdword ?
.code
main proc
mov num1,5
mov eax,num1
mov num2,eax
ret
main endp
end
I have checked the masm in the build customization of the project.
I have changed the item type to Microsoft Macro Assembler.
But, it is still showing error messages below:
Severity Code Description Project File Line Suppression State
Error A2206 missing operator in expression testing C:\Users\Kin\Desktop\assembly\testing\testing\Source.asm 3
Error A2206 missing operator in expression testing C:\Users\Kin\Desktop\assembly\testing\testing\Source.asm 2
Error MSB3721 The command "ml.exe /c /nologo /Zi /Fo"Debug\Source.obj" /W3 /errorReport:prompt /TaSource.asm" exited with code 1. testing H:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\BuildCustomizations\masm.targets 50
Changed to .stack 100h
It is now showing:
Severity Code Description Project File Line Suppression State
Error LNK1120 1 unresolved externals testing C:\Users\Kin\Desktop\assembly\testing\Debug\testing.exe 1
Error LNK2001 unresolved external symbol _WinMainCRTStartup testing C:\Users\Kin\Desktop\assembly\testing\testing\LINK 1
.386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
DumpRegs PROTO
.code
main proc
mov cx, 01h
sub cx, 2
call DumpRegs
add cx, 2 ; Clears the sign flag
invoke ExitProcess,0
main endp
end main
Errors:
1>Example.obj : warning LNK4258: directive '/ENTRY:main#0' not compatible with switch '/ENTRY:main'; ignored
1>Example.obj : error LNK2019: unresolved external symbol _DumpRegs#0 referenced in function _main#0
1>C:...: fatal error LNK1120: 1 unresolved externals
I tried looking up how to resolve this issue but have had no luck. Can anyone help me get this thing running?
SOLUTION: For those using Kip Irvine's book and trying to get their stuff to work, you can find how to create a project from scratch using the libraries in his book here (bottom): http://kipirvine.com/asm/gettingStartedVS2013/index.htm
Note that it is below his first two entrys on how to create a program which makes it somewhat difficult to find.
you need to include the library that has the dumpregs process using INCLUDE and INCLUDELIB.
I'm trying to run the following Hello Word example in x86 assembly under Windows:
global _main
extern _GetStdHandle#4
extern _WriteFile#20
extern _ExitProcess#4
section.text
_main :
; DWORD bytes;
mov ebp, esp
sub esp, 4
; hStdOut = GetstdHandle(STD_OUTPUT_HANDLE)
push - 11
call _GetStdHandle#4
mov ebx, eax
; WriteFile(hstdOut, message, length(message), &bytes, 0);
push 0
lea eax, [ebp - 4]
push eax
push(message_end - message)
push message
push ebx
call _WriteFile#20
; ExitProcess(0)
push 0
call _ExitProcess#4
; never here
hlt
message :
db 'Hello, World', 10
message_end :
But then I get the following error when trying to link the assembled .obj file:
error LNK2001: unresolved external symbol _GetStdHandle#4
error LNK2001: unresolved external symbol _WriteFile#20
error LNK2001: unresolved external symbol _ExitProcess#4
fatal error LNK1120: 3 unresolved externals
Source of my example: How to write hello world in assembler under Windows?
How to fix these? Or also, why isn't the example working for me?
When using a C compiler the standard libraries are typically linked to the code which is typically not done when calling the linker separately.
The three functions are located in "kernel32.dll" so you'll have to link against "kernel32.lib" (or "libkernel32.a" when using GNU tools).
Your entry point is "_main" so I assume you want to use the startup object files, too.
However this is not neccessary in your case so you may simply define "_main" as linker entry point and not link against the startup object files.