Copying a String into another String[solved]

Started by hungerTom, February 01, 2009, 09:07:52 PM

Previous topic - Next topic

hungerTom

Hi!

This is probably silly, but..

I've defined:

var     DB  9,0,10 dup('$')
nfvar   DB  0Dh,0Ah,0Dh,0Ah,09h,'Var   not found!',0Dh,0Ah,'$'

Now in my code, I get input from the keyboard which gets stored in var.
What I want to to is later write whatever is in var into nfvar after 'Var '
Then I want to output the new string.
So if var where MYVAR, it would read:
Var MYVAR not found!
I could probably more easily just cut up nfvar, and just output 'bit by bit', but that wouldn't be very elegant.
So, is what I want possible, if yes, how.
I've tried with movs, but its not working  :(

MichaelW

Unless you know at assembly time what the length of the input string will be, I see no choice but to break nfvar up into two parts. You would display the first part, then the input string, and then the second part. To avoid having the second part display at the start of the line, you would need to eliminate the terminating carriage return from the input string (since the carriage return would otherwise move the text cursor to the start of the current line). You could do this by substituting '$' for the carriage return. To do the substitution you would need to find the carriage return. You could calculate the index of the carriage return from the length returned in the second byte of the buffer, or you could search for it with scasb or a small loop that does the equivalent.
eschew obfuscation

hungerTom

This is what I would do, to eliminate the CR.
xor    bh,bh               
mov    bl,varpuff[1]       
mov    varpuff[bx+2],'$'

But isn't it possible to insert n number of bytes into a string?
I know the length of the string during runtime (in example above it gets moved to bl), so I was thinking that I could 'rep movsb' the input string into the outputstring.

What I'm uncertain of, and haven't gotten to work is how I can address  the exact byte from whereon n bytes get written.
To compensate, I could limit the input string to say 8 chars, and provide enough 'whitespace' in the output string that can be safely 'overwritten'.

I've tried things like [nfvar+positionbyte] but that doesn't work.
I know I probably would have to do this with a string function, which involves ES:DI and DS:DI for addressing source and destination, which I'm having difficulties in understanding/using.

FORTRANS

#3
Hello,

Quote from: hungerTom on February 02, 2009, 02:58:53 PM

But isn't it possible to insert n number of bytes into a string?

   Yes.

Quote
I know the length of the string during runtime (in example above it gets moved to bl), so I was thinking that I could 'rep movsb' the input string into the outputstring.

   Sounds good.

Quote
What I'm uncertain of, and haven't gotten to work is how I can address  the exact byte from whereon n bytes get written.
To compensate, I could limit the input string to say 8 chars, and provide enough 'whitespace' in the output string that can be safely 'overwritten'.

I've tried things like [nfvar+positionbyte] but that doesn't work.
I know I probably would have to do this with a string function, which involves ES:DI and DS:DI for addressing source and destination, which I'm having difficulties in understanding/using.

   Well quickly, so look for errors...


var      DB  9,0,10 dup('$')
nfvar    DB  0Dh,0Ah,0Dh,0Ah,09h,'Var           not found!',0Dh,0Ah,'$'

        MOV     SI,OFFSET var + 2
        MOV     DI,OFFSET nfvar + 9
        XOR     CH,CH
        MOV    CL,[var+1]
        DEC     CX
    REP MOVSB


   I added some white space to hold the copied string.  But this
should be close to what you want?

   What MichaelW was talking about (maybe) would look something
like.

nfvar1  DB        0Dh,0Ah,0Dh,0Ah,09h,'Var $'
var     DB        9,0,10 dup('$')
nfvar2   DB      '  not found!',0Dh,0Ah,'$'


   That avoids some of the variable string size problems.

HTH,

Steve N.

Edit, had CX as BX.

MichaelW

I created this before I saw FORTRANS' reply.

If you allow room for it, moving the input string into the output string should be no problem. To do the move with MOVSB you could use something like this:

    ; Load count into CX.
    xor cx, cx
    mov cl, var+1
    ; Load source and destination addresses into SI and DI.
    mov si, OFFSET var+2
    mov di, OFFSET nfvar+9   ; 9 is just a guess
    ; Set ES to the data segment (this step not necessary in .COM file).
    push ds
    pop es
    ; Move CX bytes from DS:SI to ES:DI
    rep movsb


Or you could accomplish the same thing, using more instructions, but with the code easier to understand, with something like this:

    ; Load count into CX.
    xor cx, cx
    mov cl, var+1
    ; Load source and destination addresses into SI and DI.
    mov si, OFFSET var+2
    mov di, OFFSET nfvar+9   ; 9 is just a guess
  looper:
    ; Get indexed byte from source.
    mov al, [si]
    ; Increment source index to next byte.
    inc si
    ; Store byte to destination.
    mov [di], al
    ; Increment destination index to next byte.
    inc di
    ; Decrement CX
    dec cx
    ; Loop back if CX is not zero.
    jnz looper

eschew obfuscation

hungerTom

Thanks for your help.
Quotethis should be close to what you want?

Yes, too both of you!
I can work with that.  :bg

Out of curiosity, how would one go about making this 'dynamic' , so that the input strings length no longer matters and the output string gets 'expanded' if required.
I don't need this functionality nor do I think finding a complex solution for something that quite easily is done just by splitting the output string up to be very clever  :wink.

But I can imagine situations where this could be essential...So how would one go about such a task?

I would imagine something like this:
First the input strings length is determined, a new 'output-string' would then be allocated with the original length+the input length.
Then the different parts would have to be copied into place. Finally the string could be outputted.
Especially the 'allocation-part' is where I wouldn't know what to do, at least not in assembly.  :red



MichaelW

Quote
I would imagine something like this:
First the input strings length is determined, a new 'output-string' would then be allocated with the original length+the input length.
Then the different parts would have to be copied into place. Finally the string could be outputted.

That looks workable. Allocating memory, using function 48h, is no problem. The allocated memory would be in a different segment than your program variables, so to access it you would need to load the segment address of the memory (which the function returns in AX) into a segment register.
eschew obfuscation