Here is a simple console pipe example. The executable pipe.exe reads data from STDIN and converts it to uppercase.
dir /b | pipe
BUILD.BAT
CRT0
FILES.TXT
PIPE.ASM
PIPE.EXE
PIPE.INC
SAMPLE.TXT
STDOUT.ASM
UPPERCASE.ASM
pipe "This is a test"
THIS IS A TEST
Source code :
include pipe.inc
BUFSIZE equ 1024
.data?
dwRead dd ?
buffer db BUFSIZE dup(?)
.code
main PROC C uses esi argc:DWORD,argv:DWORD
LOCAL hInput:DWORD
invoke GetStdHandle,STD_INPUT_HANDLE
mov hInput,eax
mov esi,OFFSET buffer
cmp argc,1+1
jne @f
mov edx,argv
mov esi,DWORD PTR [edx+4]
call PrintStr
ret
@@:
invoke ReadFile,hInput,esi,BUFSIZE,ADDR dwRead,NULL
test eax,eax
je @f
cmp dwRead,0
je @f
mov eax,dwRead
mov BYTE PTR [esi+eax],0
call PrintStr
jmp @b
@@:
ret
main ENDP
PrintStr PROC
invoke uppercase,esi
invoke StdOut,eax
ret
PrintStr ENDP
END
Very nice.
Where is @f, @b? Oh I miss the basics
From PellesC help:
Command line tools -> POASM macro assembler -> Introduction -> Special code labels:
QuoteSpecial code labels (IA32, AMD64)
The special label @@ can be used anywhere to create an anonymous label. This can be useful for short jumps, since you don't need to invent a new label name. For longer jumps, it's normally better to use a more descriptive name.
To jump to the nearest preceding anonymous label, use @B (back) as the jump instructions operand. To jump to the nearest following anonymous label, use @F (forward) as the operand. Since @B and @F always reference the nearest label, there is no problem having multiple anonymous labels in the same program.
Thank you timovjl
Hi CLR,
Thanks for your kind words.
You can replace anonymous labels with regular ones :
_loop:
invoke ReadFile,hInput,esi,BUFSIZE,ADDR dwRead,NULL
test eax,eax
je finish
cmp dwRead,0
je finish
mov eax,dwRead
mov BYTE PTR [esi+eax],0
call PrintStr
jmp _loop
finish:
ret
OK. Thank you Vortex.
And I spent two days searching a similar code! It is not in assembler but it does the same thing. ShellHelper is for executing a command or a batch file. It is not me who wrote it. It is a mixed of Microsoft (CreateProcess example) and others web sites and finally some ideas of mine. I made a generic function.The first code is the ShellHelper function and following it ther is an example for calling. I wrote it for my editor that creates projects and launch the compiler. For the instant only the build command seems ok.
LPSTR ShellHelper(LPSTR __lpszCommand,LPSTR __lpszDirectory)
{
alignas(HANDLE) HANDLE _hStdInPipeRead ;
alignas(HANDLE) HANDLE _hStdInPipeWrite ;
alignas(HANDLE) HANDLE _hStdOutPipeRead ;
alignas(HANDLE) HANDLE _hStdOutPipeWrite ;
alignas(HANDLE) SECURITY_ATTRIBUTES _Sa ;
alignas(HANDLE) STARTUPINFO _Si;
alignas(HANDLE) PROCESS_INFORMATION _Pi;
alignas(HANDLE) LPSTR _lpszBuffer ;
alignas(int) BOOL _bResult ;
alignas(int) char _szComSpec[256] ;
alignas(int) char _szCommand[1024] ;
_bResult = FALSE ;
_lpszBuffer = NULL ;
_hStdInPipeRead = NULL ;
_hStdInPipeWrite = NULL ;
_hStdOutPipeRead = NULL ;
_hStdOutPipeWrite = NULL ;
MemorySetTo0(&_Si,sizeof(STARTUPINFO)) ;
MemorySetTo0(&_Pi,sizeof(PROCESS_INFORMATION)) ;
MemorySetTo0(_szCommand,sizeof(_szCommand)) ;
MemorySetTo0(_szComSpec,sizeof(_szComSpec)) ;
_Sa.nLength = sizeof(SECURITY_ATTRIBUTES) ;
_Sa.lpSecurityDescriptor = NULL ;
_Sa.bInheritHandle = TRUE ;
_bResult = CreatePipe(&_hStdInPipeRead,&_hStdInPipeWrite,&_Sa,0) ;
if(!_bResult) return(NULL) ;
_bResult = CreatePipe(&_hStdOutPipeRead,&_hStdOutPipeWrite,&_Sa,0) ;
if(!_bResult) return(NULL) ;
GetEnvironmentVariable("ComSpec",_szComSpec,sizeof(_szComSpec)) ;
sqlite3_snprintf(sizeof(_szCommand),_szCommand,"%s /c \"%s\"",_szComSpec,__lpszCommand) ;
_Si.cb = sizeof(STARTUPINFO) ;
_Si.dwFlags = STARTF_USESTDHANDLES ;
_Si.hStdError = _hStdOutPipeWrite ;
_Si.hStdOutput = _hStdOutPipeWrite ;
_Si.hStdInput = _hStdInPipeRead ;
if(CreateProcess(NULL,_szCommand,NULL,NULL,TRUE,CREATE_NO_WINDOW,NULL,__lpszDirectory,&_Si,&_Pi))
{
while(WaitForSingleObject(_Pi.hProcess,5) == WAIT_TIMEOUT)
{
MSG _uMsg ;
if(PeekMessage(&_uMsg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&_uMsg) ;
DispatchMessage(&_uMsg) ;
}
}
CloseHandle(_hStdOutPipeWrite) ;
CloseHandle(_hStdInPipeRead) ;
_lpszBuffer = MemoryAlloc(65536) ;
if(_lpszBuffer)
FileRead(_hStdOutPipeRead,(unsigned char *) _lpszBuffer,65536) ;
CloseHandle(_hStdOutPipeRead) ;
CloseHandle(_hStdInPipeWrite) ;
CloseHandle(_Pi.hProcess) ;
CloseHandle(_Pi.hThread) ;
}
return(_lpszBuffer) ;
}
How to call it.
_lpszCompilation = ShellHelper(_lpszBuildFileName,_lpszProjectDirectory) ; // execute the build command
if(_lpszCompilation)
{
_lpszResult = _szResult ;
sqlite3_snprintf(sizeof(_szResult),_lpszResult,"%s\\StdOut.txt",_lpszProjectDirectory) ; // secure wsprintf
_hFile = CreateFile(_lpszResult,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL) ;
FileWrite(_hFile,(unsigned char *) _lpszCompilation,lstrlen(_lpszCompilation)) ; // Write the stdout buffer
CloseHandle(_hFile) ;
MemoryFree(_lpszCompilation) ; // frees the memory (VirtualFree)
File_FileReadExt(_lpszResult,TRUE) ; // for openning a text window in readonly mode
}
The result of the stdout fileQuote
C:\Users\Philippe\Documents\Pelles C Projects\myApp\Release>"C:\Program Files\PellesC\Bin\porc.exe" -N -L0x40c -I"C:\Program Files\PellesC\Include\Win" -I"C:\Program Files\PellesC\Include" "C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.rc" -Fo"C:\Users\Philippe\Documents\Pelles C Projects\myApp\Release\myApp.res"
C:\Users\Philippe\Documents\Pelles C Projects\myApp\Release>"C:\Program Files\PellesC\Bin\pocc.exe" -std:C17 -Tx64-coff -Gd -W2 -arch:SSE2 -Ot -Ox -Ob2 -I"C:\Program Files\PellesC\Include\Win" -I"C:\Program Files\PellesC\Include" -fp:precise -Ze -Zx -J "C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.c" -Fo"C:\Users\Philippe\Documents\Pelles C Projects\myApp\Release\myApp.obj"
C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.c(47): warning #2118: Parameter '__lParam' is not referenced.
C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.c(96): warning #2118: Parameter '__CodeNotify' is not referenced.
C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.c(96): warning #2118: Parameter '__hWndCtl' is not referenced.
C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.c(106): warning #2118: Parameter '__hWnd' is not referenced.
C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.c(113): warning #2118: Parameter '__hWnd' is not referenced.
C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.c(120): warning #2118: Parameter '__dwNewHeight' is not referenced.
C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.c(120): warning #2118: Parameter '__dwNewWidth' is not referenced.
C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.c(120): warning #2118: Parameter '__hWnd' is not referenced.
C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.c(141): warning #2118: Parameter '__lpszCmdLine' is not referenced.
C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.c(141): warning #2118: Parameter '__hPrevInstance' is not referenced.
C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.c(120): warning #2135: Static 'Main_OnSize' is not referenced.
C:\Users\Philippe\Documents\Pelles C Projects\myApp\Release>"C:\Program Files\PellesC\Bin\polink.exe" -subsystem:windows -nxcompat -machine:x64 -release -LIBPATH:"C:\Program Files\PellesC\Lib\Win64" -LIBPATH:"C:\Program Files\PellesC\Lib" @"C:\Users\Philippe\Documents\Pelles C Projects\myApp\Release\myApp.rsp" -out:"C:\Users\Philippe\Documents\Pelles C Projects\myApp\Release\myApp.exe" -map:"C:\Users\Philippe\Documents\Pelles C Projects\myApp\Release\myApp.map"
********************************
* Program created successfully *
********************************
Exiting Code 0
Here is the cmd file passed to ShellHelper
"C:\Program Files\PellesC\Bin\porc.exe" -N -L0x40c -I"C:\Program Files\PellesC\Include\Win" -I"C:\Program Files\PellesC\Include" "C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.rc" -Fo"C:\Users\Philippe\Documents\Pelles C Projects\myApp\Release\myApp.res"
@IF ERRORLEVEL 1 GOTO ERRPORC
"C:\Program Files\PellesC\Bin\pocc.exe" -std:C17 -Tx64-coff -Gd -W2 -arch:SSE2 -Ot -Ox -Ob2 -I"C:\Program Files\PellesC\Include\Win" -I"C:\Program Files\PellesC\Include" -fp:precise -Ze -Zx -J "C:\Users\Philippe\Documents\Pelles C Projects\myApp\myApp.c" -Fo"C:\Users\Philippe\Documents\Pelles C Projects\myApp\Release\myApp.obj"
@IF ERRORLEVEL 1 GOTO ERRPOCC
"C:\Program Files\PellesC\Bin\polink.exe" -subsystem:windows -nxcompat -machine:x64 -release -LIBPATH:"C:\Program Files\PellesC\Lib\Win64" -LIBPATH:"C:\Program Files\PellesC\Lib" @"C:\Users\Philippe\Documents\Pelles C Projects\myApp\Release\myApp.rsp" -out:"C:\Users\Philippe\Documents\Pelles C Projects\myApp\Release\myApp.exe" -map:"C:\Users\Philippe\Documents\Pelles C Projects\myApp\Release\myApp.map"
@IF ERRORLEVEL 1 GOTO ERRPOLINK
@GOTO SUCCESS
:ERRPORC
@ECHO ===========================
@ECHO === Errors found (PORC) ===
@ECHO ===========================
@IF EXIST .\AfterBuild.cmd @CALL .\AfterBuild.cmd 5
@ECHO Exiting Code 5
@GOTO FINISHED
:ERRPOASM
@ECHO ============================
@ECHO === Errors found (POASM) ===
@ECHO ============================
@IF EXIST .\AfterBuild.cmd @CALL .\AfterBuild.cmd 4
@ECHO Exiting Code 4
@GOTO FINISHED
:ERRPOCC
@ECHO ===========================
@ECHO === Errors found (POCC) ===
@ECHO ===========================
@IF EXIST .\AfterBuild.cmd @CALL .\AfterBuild.cmd 3
@ECHO Exiting Code 3
@GOTO FINISHED
:ERRPOLINK
@ECHO =============================
@ECHO === Errors found (POLINK) ===
@ECHO =============================
@IF EXIST .\AfterBuild.cmd @CALL .\AfterBuild.cmd 2
@ECHO Exiting Code 2
@GOTO FINISHED
:ERRPOLIB
@ECHO ============================
@ECHO === Errors found (POLIB) ===
@ECHO ============================
@IF EXIST .\AfterBuild.cmd @CALL .\AfterBuild.cmd 1
@ECHO Exiting Code 1
@GOTO FINISHED
:SUCCESS
@ECHO ********************************
@ECHO * Program created successfully *
@ECHO ********************************
@IF EXIST .\AfterBuild.cmd @CALL .\AfterBuild.cmd 0
@ECHO Exiting Code 0
@GOTO FINISHED
:FINISHED
@ECHO ON
@EXIT