Attached is a simple and very boring number guessing game. Pretty sure it gets picked up by AV, so if you feel safer the code is posted below. I wrote briefly about my thought process behind it; mainly I write stuff like this to refresh myself and put a bit more thought into research. http://krimsky.net/articles/ibasm.php (http://krimsky.net/articles/ibasm.php). Feel free to criticize on any of my MASM articles, I'm only about a week into MASM so go easy ;)
Also big thanks to hutch and vortex.
includelib libcmt.lib
includelib libvcruntime.lib
includelib libucrt.lib
includelib legacy_stdio_definitions.lib
.386
.MODEL flat,stdcall
.STACK 4096
STD_INPUT_HANDLE EQU -10 ;https://docs.microsoft.com/en-us/windows/console/getstdhandle
STD_OUTPUT_HANDLE EQU -11
GetStdHandle PROTO nStdHandle:DWORD
WriteConsoleA PROTO hConsoleOutput:DWORD, ;https://docs.microsoft.com/en-us/windows/console/writeconsole
lpBuffer:PTR BYTE,
nNumberOfCharsToWrite:DWORD,
lpNumberOfCharsWritten:PTR DWORD,
lpReserved:DWORD
ReadConsoleA PROTO hConsoleInput:DWORD, ;https://docs.microsoft.com/en-us/windows/console/readconsole
lpBuffer2:PTR BYTE,
nNumberOfCharsToRead:DWORD,
lpNumberOfCharsRead:PTR DWORD,
pInputControl:PTR BYTE
ExitProcess PROTO dwExitCode:DWORD
extern rand:NEAR
extern time:NEAR
extern srand:NEAR
extern _getch:NEAR
.data
game_randomNumber dd ?
charsWritten dd ?
msg_enternumber db "Guess a number between 0 and 9: ",0;33
msg_win db "Congratulations, your number matches the random!",13,10 ;50
msg_lose db "Sorry, your number doesn't match the random!",13,10 ;46
;lpBufferStorage db BUFFER_SIZE dup(?)
consoleHandleOutput dd ?
consoleHandleInput dd ?
.code
main PROC C
LOCAL buffer[128]:BYTE
push STD_OUTPUT_HANDLE
call GetStdHandle
mov consoleHandleOutput, eax
push STD_INPUT_HANDLE
call GetStdHandle
mov consoleHandleInput, eax
main_game:
push 0
call time
push eax
call srand ;srand(time(NULL))
call rand
xor edx, edx ;clear edx
mov ebx, 10
div ebx ;remainder is stored in edx, result in eax
mov game_randomNumber, edx ;rand() % 10
retry_label:
INVOKE WriteConsoleA, consoleHandleOutput, offset msg_enterNumber, 33, offset charsWritten, 0
INVOKE ReadConsoleA, consoleHandleInput, ADDR buffer, 128, offset charsWritten, 0
cmp charsWritten, 3 ;1 character + /r/n
jne retry_label
lea edx, buffer ;load the address of the buffer into edx
xor eax, eax ;clear eax
mov al, [edx] ;dereference value at edx, move it into the lower 8 bit section of eax
;this ensures we only move over one byte
sub eax, 48
cmp eax, 0
jb retry_label
cmp eax, 9
ja retry_label
cmp eax, game_randomNumber
je win_label
INVOKE WriteConsoleA, consoleHandleOutput, offset msg_lose, 46, offset charsWritten, 0
jmp main_game
win_label:
INVOKE WriteConsoleA, consoleHandleOutput, offset msg_win, 50, offset charsWritten, 0
call _getch
INVOKE ExitProcess, 0
main ENDP
END
i will try it. I don't know if defining the stack size is a good idea...:idea:
I don't want to be rude, but it seems like you used a c++ compiler... :idea:
Well, now looking the code you posted above, seems pretty obvious: the entry point for the program is not there and you use c (cdecl) calling convention for that 'procedure'...:shock: Is the game good? :icon_mrgreen:
Quote from: felipe on December 10, 2018, 12:12:30 PM
I don't want to be rude, but it seems like you used a c++ compiler... :idea:
VS 2017 :s
Can you explain a bit on the problem with the entry?
At first, looking at the size, I thought you had made it with Masm Basic. :badgrin:
You can reduce dramatically the size by:
1) Usingt the masm32 supplied msvcrt.lib instead of the 4 bloatware libraries.
2) Set entry point to main in Linker\Advanced to circumvent mainCRTStartup.
3) Disable SAFESEH
In the end with manifest the release version .exe will be around 4KB.
Using mainCRTStartup as proc name in console programs helps too..code
mainCRTStartup PROC C
...
mainCRTStartup ENDP
END
And linker option -nocoffgrpinfo drops a some other useless crap too.
We should have a msvcrtos.lib or something similar to express the OS version of msvcrt.dll
Quote from: AW on December 10, 2018, 09:09:12 PM
At first, looking at the size, I thought you had made it with Masm Basic. :badgrin:
You can reduce dramatically the size by:
1) Usingt the masm32 supplied msvcrt.lib instead of the 4 bloatware libraries.
2) Set entry point to main in Linker\Advanced to circumvent mainCRTStartup.
3) Disable SAFESEH
In the end with manifest the release version .exe will be around 4KB.
Hey ill take a look at the masm32 msvcrt.lib. SAFESEH already disabled, was the first thing ;) Also Ill set the entry, thanks both TimoVJL and AW
But only libucrt.lib and the entry point make a significant difference for the size. If you use ucrt.lib instead, the size will not be much different.
However, the user is expected to have the corresponding prerequisites and redistributables. When you use the masm32 supplied msvcrt.lib you don't have that problem because msvcrt.dll is there from Windows NT onwards and works the same for the common CRT function we frequently use. Of course, you know all this, I am just posting to increase my message count. :biggrin: