Search code examples
assemblyx86masm

ASSEMBLY . How can I go through a string, writing out the special characters, numbers and letters in a text file?


Here is how I wrote the text in a txt file. I used the external fclose, fopen, fprintf functions. My question is that how can I refer separately to each character, if needed how can I modify some characters?

global start
extern exit, fopen, fclose, fprintf, printf  
import exit msvcrt.dll
import fclose msvcrt.dll
import fopen msvcrt.dll
import fprintf msvcrt.dll
import printf msvcrt.dll
segment data use32 class=data
    ; ...
    name_file db "newfile.txt",0
    descriptor_file dd -1
    mod_acces db "w",0
    text db "Every letter and n9mber should be written out separetely.",0
    error_message db "Something went wrong",0

segment code use32 class=code
    start:
        ;  ... eax= fopen(name_file,mod_acces)
        push dword mod_acces
        push dword name_file
        call [fopen]
        add esp, 4*2
        
        cmp eax, 0
        JE message_error
        
        mov [descriptor_file], eax
        ; eax = fprintf(descriptor_file, text)
        push dword text
        push dword [descriptor_file]
        call [fprintf]
        add esp,4*2
        
        push dword [descriptor_file]
        call [fclose]
        add esp,4
        
        jmp end
            
        message_error:
            push dword error_message
            call [printf]
            add esp,4
            
        end:
        
        ; exit(0)
        push    dword 0      ; push the parameter for exit onto the stack
        call    [exit]       ; call exit to terminate the program ```

Solution

  • When the file is opened, instead of writing the entire text you should examine its characters one by one, modify it whenever necessary, store the character followed by NUL (to make it a zero-terminated string required by fprintf) and then write this string. Instead of

        push dword text
        push dword [descriptor_file]
        call [fprintf]
        add esp,4*2
    

    use this:

             cld
             mov esi,text  
        Next:lodsb                   ; Copy one character addressed by esi to al. Increment esi.
             cmp al,0                ; Test if its the terminating NUL.
             je Close:               ; Close the file if so.
             call TestIfModificationIsRequired 
             mov [ModifiedChar],al   ; Store modified or unmodified character.
             push dword ModifiedChar ; Print the zero-terminated string with 1 character as usual.
             push dword [descriptor_file]
             call [fprintf]
             add esp,4*2
             jmp Next                ; Continue with the next character addressed by incremented esi.
        Close:
    

    You will need to reserve a temporary string in segment data with

      ModifiedChar db '?',0