and with the seed owned by the caller.

by Michael Calkins (Login MCalkins)
ASM Forum

Edited the previous posts to add return values to DllMain and mainCRTStartup.

I rearranged the variables in the EXE's .bss section.

In this version, the caller gives a pointer to the seed. The seed is in the EXE's .bss section.

This would allow the EXE to maintain multiple separate seeds/states if it wanted.

This lets us eliminate the .data section from the DLL. This reduces the DLL by 4KB of memory and 1KB of disk space (512B directly, and another 512B presumably by shortening the section list?). The DLL needs a .text section and .edata section. I don't think it should need an .idata section. I don't know about the .reloc section.

It makes the call to Rnd a little slower.

cdecl would be more efficient, because we could leave the pointer to the seed on the stack, and call Rnd repeatedly, rather than having to push it every time. (In C++ terms, we would say in the function declaration that the pointer is constant, so the caller knows the function isn't changing the pointer on the stack.) DLLs could of course use cdecl, but DLLs are generally stdcall. (msvcrt.dll is mostly cdecl, but most other DLLs are mostly stdcall.)

Obviously, these modules (with 1 in the filenames) are incompatible with the earlier ones (without 1 in the filenames). But they should be compatible with the C++ versions (with 1 in the filenames) which I will post later.

File sizes:

2,560 testrnddll1.dll
1,536 testrndexe1.exe

The DLL should be smaller, without the .idata and maybe without the .reloc.


-------- testrnddll1.asm --------
global _Rnd

section .text                  ; read-only code

_DllMain@12:                   ; int __stdcall DllMain(void *, unsigned int, void *)
mov eax,1
ret 0xc

_Rnd:                          ; extern "C" __declspec(dllexport) unsigned int __stdcall Rnd(unsigned int *);
mov ecx,[esp+4]
mov eax,0xfd43fd
mul dword [ecx]
add eax,0xc39ec3
and eax,0xffffff
mov [ecx],eax
ret 4

-------- testrndexe1.asm --------
extern __imp__GetStdHandle
extern __imp__WriteFile
extern __imp__Rnd


section .text                  ; read-only code

_main:                         ; int mainCRTStartup(void)

mov dword [_seed],0x50000
mov word [_crlf],0xa0d

push STD_OUTPUT_HANDLE         ; nStdHandle
call [__imp__GetStdHandle]
mov [_stdout],eax

mov byte [_i],8
.outerloop:                    ; outer loop iterates 8 times, calling Rnd and printing result

push _seed
call [__imp__Rnd]
mov edx,eax
mov edi,_crlf-1

.innerloop:                    ; inner loop converts result to hex numerals

mov al,dl
and al,0xf
cmp al,9
jbe .skip
add al,'a'-('9'+1)
add al,'0'

shr edx,4
jnz .innerloop

cld                            ; otherwise WriteFile to console fails
push 0                         ; lpOverlapped
push _trash                    ; lpNumberOfBytesWritten
inc edi
mov eax,_endbuffer
sub eax,edi
push eax                       ; nNumberOfBytesToWrite
push edi                       ; lpBuffer
push dword [_stdout]           ; hFile
call [__imp__WriteFile]

dec byte [_i]
jnz .outerloop

xor eax,eax
ret                            ; from mainCRTStartup to operating system, exiting process.

section .bss                   ; read/write uninitiallized data

_buffer: resb 8
_crlf: resb 2
_i: resb 1
resb 1                         ; padding to align 4
_seed: resd 1
_stdout: resd 1
_trash: resd 1

-------- mtestrnd1.bat --------
nasm -f win32 -o testrnddll1.o testrnddll1.asm
\qb64\internal\c\c_compiler\bin\ld -s -shared --enable-auto-image-base -dy --nxcompat -o testrnddll1.dll testrnddll1.o
nasm -f win32 -o testrndexe1.o testrndexe1.asm
\qb64\internal\c\c_compiler\bin\ld -s -dy --nxcompat -o testrndexe1.exe testrndexe1.o testrnddll1.dll %windir%\system32\kernel32.dll

This message has been edited by MCalkins on Aug 5, 2017 11:52 AM

Posted on Aug 5, 2017, 11:47 AM

Respond to this message   

Return to Index

Response TitleAuthor and Date
cdecl versionMichael Calkins on Sep 16, 8:40 PM

 Copyright © 1999-2017 Network54. All rights reserved.   Terms of Use   Privacy Statement