What's wrong with this codes below? It always says an error message:
ERROR LNK2001: Unresolved external symbol _ExitProcess@4
ERROR LNK2001: Unresolved external symbol _GetStdHandle@4
ERROR LNK2001: Unresolved external symbol _ReadFile@20
ERROR LNK2001: Unresolved external symbol _WriteFile@20
ERROR LNK2001: Unresolved external symbol _winMainCrtStartup
I just practicing assembly language using masm32. I just copy the codes below from the book but it encounter errors.
.386
.MODEL FLAT
ExitProcess PROTO NEAR32 stdcall, dwExitCode:DWORD
getStdHandle PROTO NEAR32 stdcall,
nStdHandle:DWORD
ReadFile PROTO NEAR32 stdcall,
hFile:DWORD, lpBuffer:NEAR32, nNumberOfCharsToRead:DWORD,
lpNumberofBytesRead:NEAR32, lpOverlapped:NEAR32
WriteFile PROTO NEAR32 stdcall,
hFile:DWORD, lpBuffer:NEAR32, nNumberOfCharsToWrite:DWORD,
lpNumberOfBytesWritten:NEAR32, lpOverlapped:NEAR32
STD_INPUT EQU -10
STD_OUTPUT EQU -11
.STACK
.DATA
prompt BYTE "String to convert? "
CrLf BYTE 0ah, 0dh
StrIn BYTE 80 DUP (?)
read DWORD ?
written DWORD ?
hStdIn DWORD ?
hStdOut DWORD ?
.CODE
_start:
INVOKE GetStdHandle,
STD_OUTPUT
mov hStdOut, eax
INVOKE WriteFile,
hStdOut,
NEAR32 PTR prompt,
19,
NEAR32 PTR written,
0
INVOKE GetStdHandle,
STD_INPUT
mov hStdIn, eax
INVOKE ReadFile, hStdIn,
NEAR32 PTR StrIn,
80, NEAR32 PTR read,
0
mov ecx, read
lea ebx, StrIn
forCh: cmp BYTE PTR [ebx], 'A'
jl endIfUpper
cmp BYTE PTR [ebx], 'Z'
jg endIfUpper
add BYTE PTR [ebx], 'a' - 'A'
endIfUpper:
inc ebx
loop forCh
mov ecx, read
add ecx, 2
INVOKE WriteFile,
hStdOut,
NEAR32 PTR crLf,
ecx,
NEAR32 PTR written,
0
INVOKE ExitProcess, 0
PUBLIC _start
END
STD_OUTPUT EQU -11
STD_INPUT EQU -10
GetStdHandle PROTO NEAR32 stdcall,
nStdHandle:DWORD
ReadFile PROTO NEAR32 stdcall,
hFile:DWORD, lpBuffer:NEAR32, nNumberOfCharsToRead:DWORD,
lpNumberOfBytesRead:NEAR32, lpOverlapped:NEAR32
WriteFile PROTO NEAR32 stdcall,
hFile:DWORD, lpBuffer:NEAR32, nNumberofCharsToWrite:DWORD,
lpNumberofBytesWritten:NEAR32, lpOverlapped:NEAR32
.DATA
written DWORD ?
read DWORD ?
strAddr DWORD ?
strLength DWORD ?
hStdOut DWORD ?
hStdIn DWORD ?
.CODE
;outproc (source)
;Procedure to display null-terminated string
;No registers are changed; flags are not affected.
outproc PROC NEAR32
push ebp
mov ebp, esp
pushad
pushfd
mov esi, [ebp+8]
mov strAddr, esi
; find string length
mov strLength, 0
WhileChar: cmp BYTE PTR [esi],0
jz EndWhileChar
inc strLength
inc esi
jmp WhileChar
EndWhileChar:
INVOKE GetStdHandle,
STD_OUTPUT
mov hStdOut, eax
INVOKE WriteFile,
hStdOut,
strAddr,
strLength,
NEAR32 PTR written,
0
popfd
popad
pop ebp
ret 4
outproc ENDP
; inproc (dest, length)
; Procedure to input a string from keyboard.
; The string will be stored at the address given by dest.
; The lenght parameter gives the size of the user's buffer. It is
; assumed that there will be room for the stirng and a null byte.
; The stirn will be terminated by a null character (00h).
; Flags are unchanged.
inproc PROC NEAR32
push ebp
mov ebp, esp
pushad
pushfd
INVOKE GetStdHandle,
STD_INPUT
mov hStdIn, eax
mov ecx, [ebp+8]
mov strLength, ecx
mov esi, [ebp+12]
mov strAddr, esi
INVOKE ReadFile,
hStdIn,
strAddr,
strLength,
NEAR32 PTR read,
0
mov ecx, read
mov BYTE PTR [esi+ecx-2],0
popfd
popad
pop ebp
ret 8
inproc ENDP
There is no need to do prototypes for API functions. Instead use the INC and LIB files that come with MASM32.
include windows.inc
include user32.inc
include kernel32.inc
include shell32.inc
includelib user32.lib
includelib kernel32.lib
includelib shell32.lib
These ones cover most programs, however if you end up using functions that are defined in other INC/LIB files you will have to include those as well.
i think he is using Irvine32.lib
it doesn't mix well with masm32
if that is the case, he wants to
include smallwindows.inc
includelib irvine32.lib
although, i see no reason smallwindows.inc couldn't be replaced with the masm32 windows.inc