Search code examples
assemblyx86masmirvine32

How to insert string into other string at certain position in Assembly?


For my assignment, I'm trying to write Insert function like C++ insert. My function should insert one string into other string at a certain position.

Inputs:

destination : Be my friend today
source      : good
position    : 6

Output:

Be my good friend today

How should I make room in the middle of the string ?

This is my code so far.

Insert PROC PROC uses edi esi ebx ecx,
                  destination:DWORD ,
                  source:DWORD,
                  position:DWORD

    mov  esi,destination          ;add esi address of str
    add  esi,position
    add  esi,4                     ;lenght of source
    mov  edi,destination           
    add  edi,position

    ;I don't know what should I do in here

    ;How should I make room in the middle of destination ?
    ;How should I insert at certain position + source length :-(
    ;Also, I shouldn't use loop and lea. 


    rep  movsb

    Insert ENDP

Solution

  • I'm going to avoid providing any code, because I have no intention of writing your assignment for you, but I will attempt to explain how you would accomplish it.

    I am going to assume the following:

    1) destination has enough memory at its address to hold the completed string without overwriting any other variables.

    2) You actually want to insert "good " (with a trailing space), rather than "good", since if you insert "good" you'll end up with "Be my goodfriend today" (without the space between good and friend).

    3) You actually intended to specify position 5, rather than position 6, since C++ insert uses zero-based positions (position 0 is the first character, position 1 is the second, etc).

    Your first step is to copy the right-hand portion of the string in order to make room. You will copy the characters from the starting position for the insert, to the starting position plus the size of the string to insert, ending up with the following:

    destination : Be my frienfriend today
    

    There is one catch here though: you have to copy backwards from the end of destination to avoid overwriting characters that haven't been copied yet - if you start at offset 6 and copy that to offset 11, you will have overwritten the value of offset 11 that needs to be copied to offset 16 first, and you will instead end up with something like this:

    destination : Be my frienfrienfrienfri
    

    By copying backwards, you avoid that problem. A simple conditional jump with the appropriate dec or sub operators will work fine.

    After making room for the source string as specified above, its a simple matter of loading the registers properly and using rep movsb to copy the source into the destination at the specified position, overwriting the characters you have already copied.

    And with that, destination will contain "Be my good friend today".