jasmeet walia
jasmeet walia

Reputation: 11

Need help combining two strings TASM

I need help in combining two programs I have and I can't seem to get it working for me. Don't get the desired output.

So here's my problem statement:

Combine Two separate strings in a third string and display it, Where the first String is as it is and the second string is reversed.

Example:

Input:

String 1: 'Hello'

String 2: '.dlroW '

Output:

'Hello World.'

end of Example.

Now there are two ways we can go about this.

First: Use string functions.(Preferred)

Now I am fairly new to learning Assembly Language so I would like to do it using string functions so I can learn something New.

Second: Without using string functions.

Another Approach is if someone can help combining two programs, One for the concatenation of the string and the other for reversal, Note that I have written the two individual programs and they run well without any hiccups, I just can't seem to do it together. How I am going about with this is before concatenating the string I am trying to reverse it, then proceeding with the addition of the second string. But I can't seem to get it working. I've tried to the best of my knowledge.

    //Concatenation Code
.model tiny
.data
 msg1 db 10,13,"Enter the string 1: $"
 cat db 30 DUP('$')
 msg2 db 10,13,"Enter the string 2: $"
 msg3 db 10,13,"Concatenated string is: $"

.code
 mov ax,@data
 mov ds,ax
 lea dx,msg1
 mov ah,09h
 int 21h

 lea si,cat

up: mov ah,01h
    int 21h
    mov [si],al
    inc si
    cmp al,0dh
    jnz up

    lea dx,msg2
    mov ah,09h
    int 21h

    dec si

up1: mov ah,01h
     int 21h
     mov [si],al
     inc si
     cmp al,0dh
     jnz up1

     lea dx,msg3
     mov ah,09h
     int 21h

     lea dx,cat
     mov ah,09h
     int 21h

     mov ah,4ch
     int 21h
     end`

Here's Part 2

//Reversal Code
.model tiny
.data
 msg1 db 10,13,"enter the string: $"
 string db 40 DUP('$')
 rev db 40 DUP('$')
 msg2 db 10,13,"reverse string is: $"
.code
 mov ax,@data
 mov ds,ax
 lea dx,msg1
 mov ah,09h
 int 21h

 mov ah,0ah
 lea dx,string
 int 21h

 lea si,string
 lea di,rev
 mov cl,[si+1]
 mov ch,00h
 add di,cx

 inc si
 inc si

 up: mov al,[si]
     mov [di],al
     inc si
     dec di
     loop up
     inc di
     mov ah,09h
     lea dx,msg2
     int 21h

     mov ah,09h
     lea dx,[di]
     int 21h

     mov ah,4ch
     int 21h
     end 

And Here is the code I came Up with by combining those two.

//That's the code I tried Combining

.model tiny
.data
.model tiny
.data
 msg1 db 10,13,"Enter string1: $"
 cat db 30 DUP('$')
 msg2 db 10,13,"Enter string2: $"
 msg3 db 10,13,"Concatenated string is: $"

.code
 mov ax, @data
 mov ds,ax
 lea dx,msg1
 mov ah,09h
 int 21h

 lea si,cat

 up: mov ah,01h
 int 21h
 mov [si],al
 inc si
 cmp al,0dh
 jnz up
 lea dx, msg2
 mov ah,09h
 int 21h

 dec si

 up2:mov al,[si]
  mov [di],al
  inc si
  dec di
  loop up2
  inc di

 up1:mov ah,01h
 int 21h
 mov [si],al
 inc si
 cmp al,0dh
 jnz up1

 lea dx,msg3
 mov ah,09h
 int 21h

 lea dx,cat
 mov ah,09h
 int 21h

 mov ah,4ch
 int 21h
 end

My Output

As you can see clearly I have failed at doing either task correctly. So can someone tell me where I am going wrong? Or teach me how to do this using the string Functions?

Upvotes: 1

Views: 557

Answers (1)

Sep Roland
Sep Roland

Reputation: 39166

The up2 loop that tries to do string reversal comes too soon!. You've placed it where the 2nd string (the one that needs reversal) isn't even inputted yet.
If you would have written comments in your program, then you would probably have noticed this yourself.

This up2 loop uses the LOOP instruction that depends on the CX register but your program does not assign any suitable value to CX.

And also your working reversal program is using 2 buffers. Why then do you expect the combo to work from a single buffer?
Define the cat buffer so it can hold both strings.
Define the str buffer so it can hold the second string.

 lea dx, msg1
 mov ah, 09h    ; DOS.PrintString
 int 21h

 lea di, cat
up:             ; Input f i r s t string
 mov ah, 01h    ; DOS.GetCharacter
 int 21h        ; -> AL
 mov [di], al
 inc di
 cmp al, 13
 jne up

 dec di         ; Throw out the 13
                ; This marks the start of the reversed string, VERY IMPORTANT
                ; So don't change DI while inputting the 2nd string

 lea dx, msg2
 mov ah, 09h    ; DOS.PrintString
 int 21h

 lea si, str
 mov dx, si
up1:            ; Input s e c o n d string
 mov ah, 01h    ; DOS.GetCharacter
 int 21h        ; -> AL
 mov [si], al
 inc si
 cmp al, 13
 jne up1

 dec si         ; Throw out the 13
 cmp si, dx
 je  done       ; Second string was empty. CAN HAPPEN!
up2:            ; Reversed copying of s e c o n d string
 dec si
 mov al, [si]
 mov [di], al
 inc di
 cmp si, dx
 ja  up2
done:
 mov ax, 0A0Dh  ; Add a proper carriage return and linefeed to the result
 mov [di], ax
 mov al, '$'    ; Terminate the result with a dollar sign
 mov [di+2], al

 lea dx, msg3
 mov ah, 09h    ; DOS.PrintString
 int 21h

 lea dx, cat
 mov ah, 09h    ; DOS.PrintString
 int 21h

First: Use string functions.(Preferred)

Both in the up loop and in the up2 loop, do you find next pair of instructions:

mov [di], al
inc di

Provided

  • the direction flag DF is clear so that DI can increment
  • the ES segment register points to @data

you can replace these 2 instructions by a single STOSB instruction.

This is what needs to go on top of your program:

.code
 mov ax, @data
 mov ds, ax
 mov es, ax
 cld

If we allowed ourselves to write a silly sequence of multiple std (set direction flag) and cld (clear direction flag) instructions, we could also replace mov al, [si] with lodsb. Care must be taken to keep a valid SI pointer (*).

 dec si         ; (*)
up2:            ; Reversed copying of s e c o n d string
 std
 lodsb          ; Due to STD, SI will decrement
 cld
 stosb          ; Due to CLD, DI will increment
 cmp si, dx
 jae up2         ; (*)
done:
 mov ax, 0A0Dh  ; Add a proper carriage return and linefeed to the result
 stosw
 mov al, '$'    ; Terminate the result with a dollar sign
 stosb

In code that sets the direction flag (using std) it is best to end with a cld instruction so the direction flag is in the state we most expect!

Upvotes: 1

Related Questions