MS-DOS .com file -, 30 bytes
0000 fc be 82 00 b4 02 ac 88 c2 cd 21 ac 3c 0d 74 0d
0010 b2 28 50 cd 21 5a e8 f0 ff b2 29 cd 21 c3
The string is passed to the executable using the command line. (One space character between the .COM file name and the string).
The result is written to standard output.
The disassembly is here:
fc cld ; Make sure DF is not set (lodsb!)
be 82 00 mov si,0x82 ; First character of command line args
b4 02 mov ah,0x2 ; AH=2 means output for INT 21h
ac lodsb ; Load first character
88 c2 mov dl,al ; Move AL to DL (DL is written to output)
recursiveFunction:
cd 21 int 0x21 ; Output
ac lodsb ; Get the next character
3c 0d cmp al,0xd ; If it is "CR" (end of command line) ...
74 0d je doReturn ; ... return from the recursive function
b2 28 mov dl,0x28 ; Output "(" next...
50 push ax ; ... but save character read first
cd 21 int 0x21 ; (Actual output)
5a pop dx ; Restore character (but in DL, not in AL)
e8 f0 ff call recursiveFunction ; Recursively enter the function
doReturn:
b2 29 mov dl,0x29 ; Output ")"
cd 21 int 0x21
c3 ret ; Actually return
Note: You can exit a DOS .COM file (unlike files with EXE headers) using a "RET" instruction.