Search code examples
assemblyx86-16emu8086

Assembly 8086 - How to insert string buffer into another string buffer?


I'm making a program, which instead of "1bc" writes "ONEbc". However, I'm struggling to insert one string inside another. I managed to do that the program changes each char, but I need to insert a whole string, not symbol by symbol, while also my program doesn't print the rest of the text (just "ONE"). This is the segment which changes 1 into ONE.


.DATA
        one db "ONE" ; I want to include this into my code somehow

**************************************************

    MOV cx, ax
    MOV si, offset firstBuf ; (firstBuf db "1bc")
    MOV di, offset newBuf ; (should be "ONEbc" after this)
  work:
    MOV dl, [si]
    CMP dl, '1'
    JNE continue  
        ADD ax, 3     
    MOV cx, ax
    MOV [di], 'O'
    INC si
    INC di
    MOV [di], 'N'
    INC si
    INC di
    MOV [di], 'E'   
    JMP next
  continue: 
    MOV [di], dl   
  next:
    INC si
    INC di
    LOOP    work

As you can see, I have tried putting the string symbol by symbol, but I think there's a better way to do that. I'm a beginner and I'm using emu8086, if that helps.


Solution

  • The output didn't show "bc" because of the 2 additional increments on the SI register! And changing CX in the middle of the loop will cause reading past the source string, so don't do that either.

        MOV cx, ax       ; Length of the input string
      work:
        MOV dl, [si]
        INC si
        CMP dl, '1'
        JNE continue  
        ADD ax, 2        ; New length of the output string we're building
        MOV [di], 'O'
        INC di
        MOV [di], 'N'
        INC di
        MOV dl, 'E'   
      continue: 
        MOV [di], dl
        INC di
        LOOP    work
    

    I have tried putting the string symbol by symbol, but I think there's a better way to do that.

    You can output 2 characters together:

        MOV cx, ax       ; Length of the input string
      work:
        MOV dl, [si]
        INC si
        CMP dl, '1'
        JNE continue  
        ADD ax, 2        ; New length of the output string we're building
        MOV word [di], 'ON'
        ADD di, 2
        MOV dl, 'E'   
      continue: 
        MOV [di], dl
        INC di
        LOOP    work
    

    You could also retrieve the "ONE" string from somewhere else. Especially interesting if the text to insert is somewhat longer.

        MOV cx, ax       ; Length of the input string
      work:
        MOV dl, [si]
        INC si
        CMP dl, '1'
        JNE continue  
        mov bx, OFFSET one
        mov bp, 2
        add ax, bp        ; New length of the output string we're building
    nestedLoop:
        mov dl, [bx]
        inc bx
        mov [di], dl
        inc di
        dec bp
        jnz nestedLoop
        mov dl, [bx]
      continue: 
        MOV [di], dl
        INC di
        LOOP    work