1

Hi im writing a program in 80x86 assembly language using masm that concatenates two strings. What I'm attempting to do is find where the end of the first string is then add the contents of the second string onto the first. Here's the code I have so far:


.586
.MODEL FLAT
.STACK 4096
INCLUDE io.h 

.DATA
prompt      BYTE    "Input String", 0
string1     BYTE    80 DUP (?)
string2     BYTE    80 DUP (?)
displayLbl  BYTE    "Concatenated string", 0

.CODE
_MainProc PROC
        input   prompt, string1, 80 ; ask for first string
        input   prompt, string2, 80 ; repeat for second string

        lea     eax, string1        
        push    eax                 
        lea     ebx, string2
        push    ebx

        call    strConcatenation    ; procedure to concatenate the strings

        add     esp, 8              ; remove parameters
        output  displayLbl, string1 ; display result

        mov     eax, 0              ; exit with return code 0
        ret
_MainProc ENDP

strConcatenation PROC

        push    ebp
        mov     ebp, esp
        push    edi
        push    esi
        pushfd

        mov     edi, [ebp+8]
        repnz   scasb               ; scan for null in string1
        
        mov     esi, [ebp+12]
        dec     edi

        cld
whileConcStr:
        cmp     BYTE PTR [esi], 0   ; null source byte?
        je      endWhile            ; stop copying if null

        lodsb                       ; load data
        stosb                       ; store data
        jmp     whileConcStr        ; go check next byte
endWhile:
        mov     BYTE PTR [edi], 0   ; terminate destination string

        popfd                       ; restore flags
        pop     esi                 ; restore registers
        pop     edi
        pop     ebp
        ret     
        
strConcatenation ENDP

END

When I enter strings like 'assembly' and 'language' nothing changes. Any help is appreciated, thanks.

  • One comment is that `repnz` will decrement `ecx` on every iteration and terminate if it gets to zero, which you don't want. So you can set `ecx` to `-1` before starting, essentially asking for up to 2^32 repetitions. – Nate Eldredge Nov 23 '20 at 04:46
  • so I tried setting ecx to -1 and I would either get an error or the same result – ramiandamos_ Nov 23 '20 at 05:00
  • I think you have the arguments to `strConcatenation` reversed. As it stands, it is going to concatenate `string1` onto the end of `string2`, and it sounds like you want it the other way around. – Nate Eldredge Nov 23 '20 at 05:09
  • tried reversing them still doesn't work most likely the problem is in my procedure – ramiandamos_ Nov 23 '20 at 05:16
  • Oh, you have to zero out `al` before the `repne scasb`. Otherwise you are searching for some random value instead of zero. With these fixes the function works for me. – Nate Eldredge Nov 23 '20 at 05:25
  • holy crap it now works you are amazing thank you so much I was ready to just give up on it – ramiandamos_ Nov 23 '20 at 05:32

1 Answers1

1

Three bugs:

  • Your arguments to strConcatenation are reversed. As it stands you are concatenating string1 onto the end of string2.

  • repne scasb scans for the value in the al register, which you haven't initialized. To scan for nul, zero it out: xor al, al.

  • repne scasb terminates when the byte in al is found OR when ecx reaches zero (it is decremented on each iteration). You haven't initialized ecx either. To scan indefinitely until the byte is found, you can set ecx to -1.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
  • BTW, `xor eax,eax` is a more efficient way to zero AL, zeroing the whole register instead of merging a zero into the low byte of the old contents. On modern CPUs, `xor al,al` isn't special-cased as a [dependency-breaking zeroing idiom](https://stackoverflow.com/questions/33666617/what-is-the-best-way-to-set-a-register-to-zero-in-x86-assembly-xor-mov-or-and). It would of course still be correct, just slower. – Peter Cordes Nov 23 '20 at 07:30