News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Input a string

Started by Magnum, November 27, 2011, 10:02:23 PM

Previous topic - Next topic

Magnum

This won't compile right.

I looked at the input macro, but it does some modifications that won't work for
my application.

I want to input a string which will end with an Alt 219 character and have it output to a text file.


.data

.data?

storage    db    (sizeof string) dup (?) ; contains encrypted string

txtinput   db    250 (?)

.code

start:

mov txtinput, input("Type the string.")

lea          ebx, storage
mov          esi, offset txtinput

scramble:

lodsb
not          al          ; flip bits
mov          [ebx], al
inc          bx
cmp          al,'$'      ; not Û = $ (end of string marker)
jz           next
jmp          scramble

next:

dec          bx          ; backspace and write a null over
mov          al,00h      ; the '$'
mov          [ebx],al             

print ADDR storage         
invoke ExitProcess,0

Have a great day,
                         Andy

jj2007

Quote from: Magnum on November 27, 2011, 10:02:23 PM
This won't compile right.

Yes indeed. It throws lots of errors. You probably expect that now somebody guesses which error messages you are getting and in which line, which include files you are using, where "string" is defined, etc etc.

Magnum

Sorry about that Chief.


include \masm32\include\masm32rt.inc

.data

NoNo         db      ' ',0

.data?

storage      db       sizeof string dup (?) ; contains decrypted string

.code
                        ; not $ = Û (Alt 219)MUST BE AT THE END
string       db       "³"ß²žÓß'ßŒ‹–'˜ß–'ß‹—šß˜ž'ÑÛ"

start:

mov       ebx,offset storage
mov       esi,offset string

descramble:

lodsb
not          al
mov          [ebx],eax
inc          bx
cmp          al,'$'
jz           next
jmp          descramble

next:

dec          bx        ;  backspace and write a null over
mov          al,00h    ;  the '$'
mov          [ebx],al       

print ADDR storage         

invoke  MessageBox, NULL, addr storage, addr NoNo, MB_OK

; Erase the string after it's been shown in MessageBox
Burn:

xor     eax,eax
mov     edi,offset storage
mov     ecx,sizeof string
rep     stosb                   ; Zero data area

invoke ExitProcess,0

end start

Have a great day,
                         Andy

Magnum

Since there are out of the ordinary ASCII used, here is the zipped code.
Have a great day,
                         Andy

Magnum

Ignore my last few posts. Been  long weekend.

C:\masm32\SOURCE\crypt1.asm(15) : error A2006:undefined symbol : txtinput
C:\masm32\SOURCE\crypt1.asm(23) : error A2070:invalid instruction operands
C:\masm32\SOURCE\crypt1.asm(17) : warning A4014:instructions and initialized data not supported in BS

I have figured out that storage won't work because it can't determine string size since it has not been entered yet.


include \masm32\include\masm32rt.inc

.data

.data?

storage    db    (sizeof txtinput) dup (?) ; contains encrypted string

txtinput   db    250 (?)

.code

start:

mov txtinput, input("Type the string.")

lea          ebx, storage
mov          esi, offset txtinput

scramble:

lodsb
not          al          ; flip bits
mov          [ebx], al
inc          bx
cmp          al,'$'      ; not Û = $ (end of string marker)
jz           next
jmp          scramble

next:

dec          bx          ; backspace and write a null over
mov          al,00h      ; the '$'
mov          [ebx],al             

print ADDR storage         
invoke ExitProcess,0

end start

Have a great day,
                         Andy

dedndave

hi Andy,
that's not how the "input" macro works
it sets the dword pointer value to the address of a buffer that the macro has created for you
comment * -------------------------------------

    use the "input" macro as follows,

    If you want a prompt use this version
    mov lpstring, input("Type text here : ")

    If you don't need a prompt use the following
    mov lpstring, input()

    NOTE : The "lpstring" is a preallocated
           DWORD variable that is either LOCAL
           or declared in the .DATA or .DATA?
           section. Any legal name is OK.

    LIMITATION : MASM uses < > internally in its
    macros so if you wish to use these symbols
    in a prompt, you must use the ascii value
    and not use the symbol literally.

    EXAMPLE mov var, input("Enter number here ",62," ")

    ------------------------------------------- *

    input MACRO prompt:VARARG
      LOCAL txt
      LOCAL buffer
      IFNB <prompt>
        .data
          txt db prompt, 0
          align 4
        .data?
          buffer db 132 dup (?)
          align 4
        .code
        invoke StdOut,ADDR txt
        invoke StdIn,ADDR buffer,128
        mov BYTE PTR [buffer+eax], 0
        invoke StripLF,ADDR buffer
        EXITM <OFFSET buffer>
      ELSE
        .data?
          buffer db 132 dup (?)
          align 4
        .code
        invoke StdIn,ADDR buffer,128
        mov BYTE PTR [buffer+eax], 0
        invoke StripLF,ADDR buffer
        EXITM <OFFSET buffer>
      ENDIF
    ENDM


if you need a buffer larger than 128 bytes, you'll have to write your own MACRO, or just use the StdIn PROC

Magnum

This is something simpler.

I would like to get the text that is typed at the command line stored so I can process it.


   .code                       

start:                         
    call main                 

    exit

main proc

    LOCAL txtinput:DWORD        ; a "handle" for the text returned by "input"

    mov txtinput, input("Type some text at the cursor : ")
   
    ret

main endp

end start       
Have a great day,
                         Andy

dedndave

try this out
        INCLUDE    \masm32\include\masm32rt.inc

;-------------------------------------------------------------------------

        .data

szPrompt db 'OK, Type something: ',0

        .data?

txtinput   db    250 dup(?)

;-------------------------------------------------------------------------

        .code

start:
        print   offset szPrompt
        INVOKE  StdIn,offset txtinput,sizeof txtinput
        mov byte ptr txtinput[eax-1],0
        print   offset txtinput
        print   chr$(13,10)
        inkey
        exit

;-------------------------------------------------------------------------

        end     start

Magnum

Thanks Dave.

This came out of my laboratory.

It prints the right output on the screen but no longer sends it to a text file like it used to
when I redirected the output.

test.exe > text.txt

I noticed that the stored string contains a newline which isn't needed for my app.

test.exe > text.txt


include \masm32\include\masm32rt.inc

.data

szPrompt db 'Type string to be encrypted and end with Alt 219.',0

.data?

txtinput   db    250 dup(?)  ; contains plain text
storage    db    250 dup (?) ; contains encrypted string

.code

start:

print   offset szPrompt
INVOKE  StdIn,offset txtinput,sizeof txtinput

lea          ebx, storage
mov          esi, offset txtinput

scramble:

lodsb
not          al          ; flip bits
mov          [ebx], al
inc          bx
cmp          al,'$'      ; not Û = $ (end of string marker)
jz           next
jmp          scramble

next:

dec          bx          ; backspace and write a null over
mov          al,00h      ; the '$'
mov          [ebx],al             

print ADDR storage         
invoke ExitProcess,0

end start

Have a great day,
                         Andy

dedndave

yah - it would require some special code to modify the redirected buffer
it would be easier to accept the user input, modify the buffer termination as desired, then write a file

Magnum

This works, but if I forget to end with the Alt 219, Mr. Olly makes an entrance.


include \masm32\include\masm32rt.inc

CTEXT macro Text
    local szText
    .data
    szText byte Text, 0
    .code
    exitm <offset szText>   
endm


.data

szPrompt db 10,13,"Type string of up to 127 characters to be encrypted",10,13
         db "and end with Alt 219 (Use the numeric keypad for 219).",0

.data?

txtinput   db    128 dup(?)  ; contains plain text
storage    db    128 dup(?) ; contains encrypted string
dwBytes    dw    ?

.code

start:

print   offset szPrompt
INVOKE  StdIn,offset txtinput,sizeof txtinput

;mov     byte ptr txtinput[eax-1],0
;print   offset txtinput
;print   chr$(13,10)
;inkey


lea          ebx, storage
mov          esi, offset txtinput

scramble:

lodsb
not          al          ; flip bits
mov          [ebx], al
inc          bx
cmp          al,'$'      ; not Û = $ (end of string marker)
jz           next
jmp          scramble

next:

dec          bx          ; backspace and write a null over
mov          al,00h      ; the '$'
mov          [ebx],al             

invoke CreateFile,CTEXT("Enc_Str.txt"), GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, \
0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0

mov ebx, eax
invoke WriteFile, ebx, ADDR storage, SIZEOF storage, addr dwBytes, 0

invoke CloseHandle, ebx



;print ADDR storage     ; display zero terminated string
   
invoke ExitProcess,0

end start

Have a great day,
                         Andy

dedndave

well - your loop makes no test on buffer length
maybe the easiest way to fix it is to place a termination character at the end of the buffer before the loop

there is another problem in the loop, as well
that is that you INC BX and DEC BX
you should INC EBX and DEC EBX
there is a possiblity that a carry into the upper word of EBX is lost   :P
not to mention, DEC and INC EBX are single-byte instructions
DEC and INC BX are 2-byte instructions
        mov     ebx, offset storage
        mov     esi, offset txtinput
        mov byte ptr [ebx+(sizeof storage-1)],'$' xor 0FFh

descramble:
        lodsb
        not     al                    ; flip bits
        mov     [ebx], al
        inc     ebx
        cmp     al,'$'                ; not Û = $ (end of string marker)
        jnz     descramble

        mov byte ptr [ebx-1],0        ; the '$'


could just as well use EDI   :P
        mov     edi, offset storage
        mov     esi, offset txtinput
        mov byte ptr [edi+(sizeof storage-1)],'$' xor 0FFh

descramble:
        lodsb
        not     al                    ; flip bits
        stosb
        cmp     al,'$'                ; not Û = $ (end of string marker)
        jnz     descramble

        mov byte ptr [edi-1],0        ; the '$'