This program is designated for demonstration and testing of the base functions from 64bit Windows Application Binary Interface macrolibrary winabi.htm : WinABI, GetArgCount, GetArg, GetEnv, StdInput, StdOutput, TerminateProgram.
%StdConsole %SETB Yes ; Set StdOutput Console mode, which displays ANSI and WIDE strings correctly. EUROASM CPU=X64,SIMD=Enabled EUROASM UNICODE=Yes ; or UNICODE=No. twinabi can be assembled in any Unicode mode. twinabi PROGRAM Format=PE,Width=64,Entry=Main: INCLUDE winabi.htm, cpuext%^WIDTH.htm Main: PROC %IF %^UNICODE %CharMode %SET WIDE %ELSE %CharMode %SET ANSI %ENDIF StdOutput ="twinabi.exe is demo of macrolibrary winabi.htm assembled in %CharMode mode.",Eol=Yes ; Test GetArg, display count and values of arguments from command line: GetArgCount ; Count the command-line arguments. JC .Abort: MOV [ArgCount],RCX MOV EAX,ECX StoD ArgCount$ ; Convert binary number RAX to a decimal ANSI string. JC .Abort: StdOutput Eol=Yes StdOutput =B"%^PROGRAM launched with ", ArgCount$, =B" arguments:", Unicode=No, Eol=Yes JC .Abort: SUB EBX,EBX ; EBX will be the ordinal number of each argument. .EchoArg: CMP RBX,[ArgCount] JA .EchoEnv: ; Jump when all arguments have been echoed. MOV EAX,EBX StoD ArgNr$ ; Convert binary number RAX to a decimal ANSI string. SUB EAX,EAX STOSB ; Zero-terminate the argument ordinal number. GetArg RBX ; Retrieve RBX-th argument to RSI,RCX. JC .Abort: MOV EAX,ECX ; Argument size in bytes. StoD ArgSize$ ; Convert binary number RAX to a decimal string. SUB EAX,EAX STOSB ; Zero-terminate the argument size. StdOutput ArgNr$, =B".[", ArgSize$, =B"]: ", Unicode=No StdOutput RSI, Size=RCX, Eol=Yes ; Echo the argument value. JC .Abort: INC EBX JMP .EchoArg: ; Test PutEnv, display value of three variables, their retrieved (ECX) and required (EAX) size: .EchoEnv: StdOutput Eol=Yes StdOutput ='Environment strings:', Eol=Yes envNr %FOR 1,2,3 StdOutput EnvName%envNr,=" [", PutEnv EnvName%envNr,EnvVal%envNr PUSHF PUSH RCX StoD ReqSize$ ; Convert binary number RAX to a decimal ANSI string. SUB EAX,EAX STOSB POP RAX StoD EnvSize$ ; Convert binary number RAX to a decimal ANSI string. SUB EAX,EAX STOSB StdOutput EnvSize$,=B" retrieved, ",ReqSize$,=B" required]: ",Unicode=No POPF JC .Bad%envNr StdOutput EnvVal%envNr,Eol=Yes JMP .Next%envNr: .Bad%envNr:StdOutput =B" is too big or not found.",Eol=Yes,Unicode=No .Next%envNr: %ENDFOR envNr ; Test StdInput and StdOutput with four combinations of ANSI/WIDE and File/Console access method: StdOutput Eol=Yes StdOutput ="Standard input and output demonstration:",Eol=Yes unicode %FOR No,Yes console %FOR No,Yes StdOutput =B"Input/Output mode: Unicode=%unicode, Console=%console", \ Eol=Yes, Console=No, Unicode=No StdOutput =B"Enter some text: ", Console=No, Unicode=No StdInput Buffer, Console=%console, Unicode=%unicode JC .Abort: MOV EAX,ECX ; Text size including CR+LF. StoD BufSize$ ; Convert binary number RAX to a decimal string. SUB EAX,EAX STOSB ; Zero-terminate the string. StdOutput =B"Entered[",BufSize$,=B"]: ", Console=No, Unicode=No StdOutput Buffer, Size=RCX, Eol=Yes, Console=%console, Unicode=%unicode JC .Abort: %ENDFOR console %ENDFOR unicode StdOutput =B"%^PROGRAM terminated.", Console=No, Unicode=No TerminateProgram Errorlevel=0 .Abort: StdOutput =B"Aborted, some macro returned CF.",Eol=Yes,Console=No,Unicode=No TerminateProgram Errorlevel=4 ENDP Main: EnvName1 D "OS",0 EnvName2 D "PATH",0 EnvName3 D "UNDEFINED",0 EnvVal1 D "1111111111111111",0 EnvVal2 D "2222222222222222",0 EnvVal3 D "3333333333333333",0 ArgCount DQ Q ArgCount$ DB 8*B ArgNr$ DB 8*B ArgSize$ DB 8*B EnvSize$ DB 8*B ReqSize$ DB 8*B BufSize$ DB 8*B Buffer DB 256*B ENDPROGRAM twinabi