The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: bcddd214 on April 27, 2011, 02:53:41 AM

Title: How do you read a string into an array?
Post by: bcddd214 on April 27, 2011, 02:53:41 AM
I have been working with numbers and now tinkering around with strings and arrays.

If the string is an unknown size and requires user input, what is the best approach for this?
Title: Re: How do you read a string into an array?
Post by: Tight_Coder_Ex on April 27, 2011, 03:23:19 AM
I most often use stack for input and when the actuall size is known, then either use memory that's already been allocated or grab whatever I need from heap.  This is assuming your input is 4096 characters or less.
Title: Re: How do you read a string into an array?
Post by: dedndave on April 27, 2011, 03:38:32 AM
for console input, you can usually just limit the number of input characters to some number larger than needed
in most cases, that is less than 256 bytes
the input functions let you set the limit by telling it how large the buffer is
many win32 functions that have a variable-length buffer work that way
so - for that size, it doesn't hurt to declare the buffer in .DATA?
the stack is a nice way to go, also, if it is temporary data
if you want to keep the info permanently, DB is easier   :P
Title: Re: How do you read a string into an array?
Post by: mineiro on April 27, 2011, 04:09:45 AM
you can put in the first byte preceding the string, the number of bytes of that string.
if you have a string "hello", you store it in your array like "5""hello". Five here means 5 characters follow.
But you need limit the number of input characters, like Sr Dedndave sayd. In this example, is limited to 255 and not 256, continue reading.
How you know where is the next entry in your table(array) that are free to insert a new string?
You search for the next entry that have a 0(zero) preceding the string. This is why you can get 255 maximum chars and not 256.

Another way is:
You can insert a 0(zero, or another character that the user will neve input) in the end of string, so you know where it ends.
But how you know where is the next avaliable entry to your array?
You search for two zeros (00).

You can mix both ways above too, like inserting the count of chars in the start of each index, and put a zero in the end of each string.
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 27, 2011, 04:18:59 AM
Quote from: Tight_Coder_Ex on April 27, 2011, 03:23:19 AM
I most often use stack for input and when the actuall size is known, then either use memory that's already been allocated or grab whatever I need from heap.  This is assuming your input is 4096 characters or less.

I know this word heap. It refers to the reserved memory for a hash?

for this purpose, I would like to assume that a persons name is less than 30 characters.

Insight as to what to do if it was a million character would be nice but I am only looking to build a little program that assumes the normal length of a name.

Whats the best method my friend?
Title: Re: How do you read a string into an array?
Post by: hutch-- on April 27, 2011, 04:20:10 AM
You can do an array in the data section something like this.


.data?
  mbr1 db 256 dup (?)
  mbr2 db 256 dup (?)
  mbr3 db 256 dup (?)
  mbr4 db 256 dup (?)
  mbr5 db 256 dup (?)
  mbr6 db 256 dup (?)

.data
  parr dd mbr1, mbr2, mbr3, mbr4, mbr5, mbr6


parr is the pointer to the array of 6 members.

If you are writing an array of large unknown size members, you get the length first IE: from a file, allocate memory for each item and place that in a pointer array. You have to remember to de-allocate the memory for each array member if you take this approach.
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 27, 2011, 04:20:58 AM
Quote from: mineiro on April 27, 2011, 04:09:45 AM
you can put in the first byte preceding the string, the number of bytes of that string.
if you have a string "hello", you store it in your array like "5""hello". Five here means 5 characters follow.
But you need limit the number of input characters, like Sr Dedndave sayd. In this example, is limited to 255 and not 256, continue reading.
How you know where is the next entry in your table(array) that are free to insert a new string?
You search for the next entry that have a 0(zero) preceding the string. This is why you can get 255 maximum chars and not 256.

Another way is:
You can insert a 0(zero, or another character that the user will neve input) in the end of string, so you know where it ends.
But how you know where is the next available entry to your array?
You search for two zeros (00).

You can mix both ways above too, like inserting the count of chars in the start of each index, and put a zero in the end of each string.

can't you just set the variable to 'offset' and let it grow in an array?
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 27, 2011, 04:24:23 AM
I just want to read (via user input) a name into a register.
Push into an array
pop it out
then push it in backwards (working with LIFO).

Title: Re: How do you read a string into an array?
Post by: hutch-- on April 27, 2011, 04:26:14 AM
That won't work, you ned allocated memory and place a pointer to that memory in a register.
Title: Re: How do you read a string into an array?
Post by: dedndave on April 27, 2011, 04:35:34 AM
one way to do what you want would be to create an array of string like Hutch said
  mbr1 db 256 dup (?)
  mbr2 db 256 dup (?)
  mbr3 db 256 dup (?)
  mbr4 db 256 dup (?)
  mbr5 db 256 dup (?)
  mbr6 db 256 dup (?)

then, instead of trying to push the name entered onto the stack, push the address of the name onto the stack
then, the addresses will pop off in reverse order, as desired

in this case, you do not need an array of pointers
  parr dd mbr1, mbr2, mbr3, mbr4, mbr5, mbr6
because each string buffer is 256 bytes
it is easy to calculate the address of a particular one by multiplying the index by 256 and adding the address of the first one
(256 being a power of 2 makes the multiplication very simple)

the strings above may be numbered 1 through 6, but those are just names   :P
you may refer to them as 0 through 5
then use that as the index

so, if you want the 4th string (index = 3)
offset mbr1 + 256*3 is the address
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 27, 2011, 04:41:33 AM
Quote from: dedndave on April 27, 2011, 03:38:32 AM
for console input, you can usually just limit the number of input characters to some number larger than needed
in most cases, that is less than 256 bytes
the input functions let you set the limit by telling it how large the buffer is
many win32 functions that have a variable-length buffer work that way
so - for that size, it doesn't hurt to declare the buffer in .DATA?
the stack is a nice way to go, also, if it is temporary data
if you want to keep the info permanently, DB is easier   :P

Everything is temporary 'per se'. I am just trying to make sure I have a REAL good understanding of the registers and pop. None of what I am doing has any real world application. Just getting past the learning curve is all.
Title: Re: How do you read a string into an array?
Post by: dedndave on April 27, 2011, 04:43:40 AM
well - using the stack is a good idea when the information is only needed briefly
it does not "waste" unused memory

i use it, myself, quite often   :bg
sometimes, i want to make room on the stack for a small buffer
        pushad
the PUSHAD instruction pushes all 8 registers on the stack with a single byte
i may not care what is there - i just want to make some room - lol
in many cases, win32 functions want a structure that begins with the size of that structure
        mov     edi,sizeof SOMESTRUCTURE
        pushad

because the EDI register is the last of the 8 to be pushed, my structure size is already initialized   :P
ESP points to the base of the structure
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 27, 2011, 04:44:20 AM
Quote from: mineiro on April 27, 2011, 04:09:45 AM
you can put in the first byte preceding the string, the number of bytes of that string.
if you have a string "hello", you store it in your array like "5""hello". Five here means 5 characters follow.
But you need limit the number of input characters, like Sr Dedndave sayd. In this example, is limited to 255 and not 256, continue reading.
How you know where is the next entry in your table(array) that are free to insert a new string?
You search for the next entry that have a 0(zero) preceding the string. This is why you can get 255 maximum chars and not 256.

Another way is:
You can insert a 0(zero, or another character that the user will neve input) in the end of string, so you know where it ends.
But how you know where is the next avaliable entry to your array?
You search for two zeros (00).

You can mix both ways above too, like inserting the count of chars in the start of each index, and put a zero in the end of each string.

Wait, wouldn't 'offset' handle this?
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 27, 2011, 04:46:52 AM
Quote from: hutch-- on April 27, 2011, 04:26:14 AM
That won't work, you ned allocated memory and place a pointer to that memory in a register.

I know, your locked in on 256. Your seeing what I am supposed to.
I am the baby looking for what is possible.

Lets assume UNDER 256 and work in a really safe realm.

:)
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 27, 2011, 04:48:49 AM
Quote from: dedndave on April 27, 2011, 04:35:34 AM
one way to do what you want would be to create an array of string like Hutch said
  mbr1 db 256 dup (?)
  mbr2 db 256 dup (?)
  mbr3 db 256 dup (?)
  mbr4 db 256 dup (?)
  mbr5 db 256 dup (?)
  mbr6 db 256 dup (?)

then, instead of trying to push the name entered onto the stack, push the address of the name onto the stack
then, the addresses will pop off in reverse order, as desired

in this case, you do not need an array of pointers
  parr dd mbr1, mbr2, mbr3, mbr4, mbr5, mbr6

I like this "push the address of the name onto the stack
then, the addresses will pop off in reverse order, as desired"
Your pushing me into pointers which was going to be my next question.....   :)
because each string buffer is 256 bytes
it is easy to calculate the address of a particular one by multiplying the index by 256 and adding the address of the first one
(256 being a power of 2 makes the multiplication very simple)

the strings above may be numbered 1 through 6, but those are just names   :P
you may refer to them as 0 through 5
then use that as the index

so, if you want the 4th string (index = 3)
offset mbr1 + 256*3 is the address

You appear to be creating a number of arrays?
Title: Re: How do you read a string into an array?
Post by: hutch-- on April 27, 2011, 05:05:17 AM
There is some virtue in using an array of pointers, you can leave it in memory without having to protect the stack and work on it in any oder you want later. Transient techniques like pushing an popping the stack will do the job but unless you store it somewhere you have to process the data immediately or you lose it. Now RE: loading unknown sized data of any size up to very large, you can write a more complex routine that does a memory probe each iteration to see if the added data goes past the end of the current allocated memory, if it does you reallocate the buffer to a larger size so it handles the extra data.

Its messy to code correctly but is extendable to the final limit of memory automatically.
Title: Re: How do you read a string into an array?
Post by: dedndave on April 27, 2011, 05:17:31 AM
the real beauty is...
it's assembly language
you can do it which ever way is best for a given situation
Title: Re: How do you read a string into an array?
Post by: RuiLoureiro on April 27, 2011, 03:44:48 PM
Quote
  How do you read a string into an array
        1. First we must define MAXLENGTH=255  (for example, may be 1000...)
           and last index in the array MAXINDEX=2000 (for 2000 strings)
           Do MAXLENGTH1=MAXLENGTH+1 (for null terminated strings)
           
        2. Alloc buffer to that array (MyStrArray)
           Alloc buffer to READ each string from keyb (AnyString)
           
;-------------
MAXLENGTH   equ 255
MAXLENGTH1  equ MAXLENGTH+1
MAXINDEX    equ 2000

.DATA   
        AnyString   db MAXLENGTH1 + 5 dup (?)  
        MyStrArray  db MAXLENGTH1 * MAXINDEX dup (?)    
;-------------

        3. Read the string to AnyString
       
        4. Call your proc to put that string inside MyStrArray in the
           position N (index N - valid indexes are 1 to MAXINDEX, 0 is invalid ok)

           To calculate the position we do (when index N is in EBX)
           
           mov      edi, offset MyStrArray
           mov      eax, MAXLENGTH1
           sub      ebx, 1                                ; ebx=0 is invalid
           mul      ebx
           add      edi, eax                ; EDI points to MyStrArray[N]
;--------------------------------------------------
If we choose MAXLENGTH = 63

           To calculate the position we do (when index N is in EBX)

           mov      edi, offset MyStrArray
           sub      ebx, 1
           shl      ebx, 6                  ; multiply ebx by 64
           add      edi, ebx                ; EDI points to MyStrArray[N]
Title: Re: How do you read a string into an array?
Post by: mineiro on April 27, 2011, 04:51:43 PM

        TITLE   Random
        INCLUDE Irvine32.inc

        .DATA?
MAX = 80                     ;max chars allowed to read
stringIn BYTE MAX+1 DUP (?)  ;room for null
ARRAY_SIZE = 10000
MyArray byte ARRAY_SIZE dup(?) ;creates an empty array of ARRAY_SIZE bytes

        .DATA

ARRAY_LENGHT DWORD 0
PTR_ROOM DWORD 0
intro byte "press enter in a blank line to exit this loop, while this",0dh,0ah,00h
intro1 byte "now, showing what you have typed",0dh,0ah,00h
name1 byte "enter some name: ",00h
error byte "oops, cannot insert this string, don't have free space in array",00h

        .CODE
main    PROC
;array with variable input string

        call    Clrscr ;clear the screen
        mov     edx, offset intro ;present the intro
        call    WriteString ;show intro on screen
include_next:
        mov     edx, offset name1 ;enter some name
        call    WriteString
mov ecx,80 ;max allowable number of chars, Irvine rules.
mov  edx,OFFSET stringIn ;the buffer that hold the string
mov  ecx,MAX            ;buffer size - 1
call ReadString ;return in eax the number of chars typed
mov esi, offset stringIn ;source
mov edi, offset MyArray ;destin

cmp eax,0 ;the user have typed a enter? Irvine rules here.
jne have_space ;no, so store what he have typed in array
jmp ended ;yes, so end

have_space:
add ARRAY_LENGHT,1 ;room for the counter
add ARRAY_LENGHT,eax ;in eax have the number of chars typed by the user
cmp ARRAY_LENGHT,ARRAY_SIZE ;the array is full?
jb include1 ;no, so find next room
mov edx, offset error ;yes, show error to user
call    WriteString
call WaitMsg
jmp ended ;and go to the end

include1:
add edi,PTR_ROOM ;moment1 is 0
mov byte ptr [edi],al ;we store first the counter of typed chars
inc PTR_ROOM ;and add 1 to ptr_room because counter have 1 byte
add PTR_ROOM,eax ;and add eax(al) because number or chars user have typed
inc edi ;next place
mov cl,al ;the counter goes to cl
again:
lodsb ;read 1 byte from our buffer
stosb ;and store in array
loop again ;and do this cl times
jmp include_next ;loop again
ended:
        call    Clrscr ;clear the screen
        mov     edx, offset intro1 ;show some intro to user
        call    WriteString
mov esi, offset MyArray ;esi == ptr to my array
cmp byte ptr [esi],0 ;is the first byte of array 0? so the user dont have inserted nothing in it, go out
je endend
again2:
lodsb ;load byte from buffer
cmp al,0 ;is zero? we get the end of array
je endend
mov cl,al ;that byte is a counter
continue_eco:
lodsb ;read cl times it and show a char in screen
call WriteChar
loop continue_eco
call Crlf
jmp again2
endend:
call WaitMsg
        exit
main    ENDP

        END     main
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 28, 2011, 02:50:44 AM
It get to the prompt and loops to the prompt again. I am trying to integrate a 'show_array' and see if the data is even making it in.

Here are a few questions:

stringIn BYTE MAX+1 DUP (?)  ;room for null
**Why room for null? What does null look like in this case?**

lodsb
***** How Does this work?******

I went over the code and can't figure out why she won't exit the loop or show the array data?

**********************code*************************

        TITLE   Random
        INCLUDE Irvine32.inc

        .DATA?
      
MAX = 80                     ;max chars allowed to read
stringIn BYTE MAX+1 DUP (?)  ;room for null
ARRAY_SIZE = 10000
MyArray byte ARRAY_SIZE dup(?) ;creates an empty array of ARRAY_SIZE bytes

        .DATA
Index       dd 0        ; define this Index
ARRAY_LENGHT DWORD 0
PTR_ROOM DWORD 0
intro byte "press enter in a blank line to exit this loop, while this",0dh,0ah,00h
intro1 byte "now, showing what you have typed",0dh,0ah,00h
name1 byte "enter some name: ",00h
error byte "oops, cannot insert this string, don't have free space in array",00h

        .CODE
main    PROC
;array with variable input string

        call    Clrscr ;clear the screen
        mov     edx, offset intro ;present the intro
        call    WriteString ;show intro on screen
include_next:
        mov     edx, offset name1 ;enter your name
        call    WriteString
      mov ecx,80
      mov  edx,OFFSET stringIn ;the buffer that hold the string
      mov  ecx,MAX            ;buffer size - 1
      call ReadString ;return in eax the number of chars typed
      mov esi, offset stringIn ;source
      mov edi, offset MyArray ;destin

      cmp eax,0 ;the user have typed a enter? Irvine rules here.
      jne have_space ;no, so store what he have typed in array
      call ShowArray
      call DumpRegs
      jmp ended ;yes, so end

have_space:
      add ARRAY_LENGHT,1 ;room for the counter
      add ARRAY_LENGHT,eax ;in eax have the number of chars typed by the user
      cmp ARRAY_LENGHT,ARRAY_SIZE ;the array is full?
      jb include1 ;no, so find next room
      mov edx, offset error ;yes, show error to user
      call    WriteString
      call WaitMsg
      jmp ended ;and go to the end

include1:
      add edi,PTR_ROOM ;moment1 is 0
      mov byte ptr [edi],al ;we store first the counter of typed chars
      inc PTR_ROOM ;and add 1 to ptr_room because counter have 1 byte
      add PTR_ROOM,eax ;and add eax(al) because number or chars user have typed
      inc edi ;next place
      mov cl,al ;the counter goes to cl
again:
      lodsb ;read 1 byte from our buffer
      stosb ;and store in array
      loop again ;and do this cl times
      jmp include_next ;loop again
ended:
        call    Clrscr ;clear the screen
        mov     edx, offset intro1 ;show some intro to user
        call    WriteString
      mov esi, offset MyArray ;esi == ptr to my array
      cmp byte ptr [esi],0 ;is the first byte of array 0? so the user dont have inserted nothing in it, go out
      je endend
again2:
       ;load byte from buffer
      cmp al,0 ;is zero? we get the end of array
      je endend
      mov cl,al ;that byte is a counter
continue_eco:
      lodsb ;read cl times it and show a char in screen
      call WriteChar
      loop continue_eco
      call Crlf
      jmp again2
endend:
call WaitMsg
        exit
main    ENDP

ShowArray       proc
                mov     edi, offset MyArray
                xor     ebx, ebx
    _next:      cmp     ebx, Index
                jne     @F
                ret
        @@:     mov     eax, [edi+ebx]    ; get EAX from the array
                add     ebx, 4            ; point to next dword
                call WriteInt
;            call Crlf
            jmp     _next
            ret
ShowArray       endp

        END     main
Title: Re: How do you read a string into an array?
Post by: mineiro on April 28, 2011, 03:25:46 AM
Null is zero, in Irvine it mark the end of string.
From irvine book:
A null byte is stored following the characters input, but the trailing carriage return and line feed characters are not placed into the buffer.
   ECX should always be smaller that the buffer size (never equal to the buffer size) because the null byte could be the (ECX+1)th character stored.
So if your buffer have 2 bytes, you can only put one byte in it using Irvine, because it reserve some space to put a null(zero) byte at the end.

lodsb works like: read one byte from the pointer of esi and put this byte in al register, increase esi.
stosb works like: get the byte in al register and put it in the addres that edi point, increase edi.

a pseudo code for lodsb is:
mov esi, offset MyArray
mov al, byte ptr esi
inc esi

a pseudo code for stosb is:
mov edi, offset MyArray
mov byte ptr edi, al
inc edi

I don't understand why you are trying to put ShowArray procedure inside this one, if you explain, I can try to answer bcddd214.
regards.
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 28, 2011, 03:41:09 AM
Mainly to make sure I understand it.
I tried the code and even a null space would not jump the loop so I was doing some experimenting to see if I could just dump the contents of the array out and see what was going on..
Title: Re: How do you read a string into an array?
Post by: mineiro on April 28, 2011, 04:44:52 AM
alright, I get the point, insert this in the previous example to show 256 bytes of MyArray in hexadecimal format.
You will see that it start only with zeros, and after each typed string, it get filled.

include_next:
;insert the lines below
      mov      esi, offset MyArray
      mov      ecx,256
      mov      ebx,1
      call    dumpmem
;ends here your insertion
        mov     edx, offset name1   ;enter some name
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 28, 2011, 11:02:02 AM
I still can't get it to escape out?
I try with a null space and without?
Title: Re: How do you read a string into an array?
Post by: mineiro on April 28, 2011, 11:56:20 AM
change this:
intro   byte   "press enter in a blank line to exit this loop, while this",0dh,0ah,00h
to this:
intro   byte   "press \ in a blank line to exit this loop, while this",0dh,0ah,00h

and change this:
      mov      esi, offset stringIn   ;source
      mov      edi, offset MyArray      ;destin
      cmp      eax,0               ;the user have typed a enter? Irvine rules here.
      jne      have_space            ;no, so store what he have typed in array
      jmp      ended               ;yes, so end
have_space:


to this:
      mov      esi, offset stringIn   ;source
      mov      edi, offset MyArray      ;destin
      cmp      byte ptr stringIn,"\"
      je      ended
have_space:


now, if you press "\" in keyboard you exit the first loop.
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 28, 2011, 12:40:00 PM
 Assembling: 3-input-string-array.asm
3-input-string-array.asm(66) : error A2006: undefined symbol : intro1
3-input-string-array.asm(15) : error A2206: missing operator in expression
Press any key to continue . . .

***********************code**************************

        TITLE   Random
        INCLUDE Irvine32.inc

        .DATA?
      
MAX = 80                     ;max chars allowed to read
stringIn BYTE MAX+1 DUP (?)  ;room for null
ARRAY_SIZE = 10000
MyArray byte ARRAY_SIZE dup(?) ;creates an empty array of ARRAY_SIZE bytes

        .DATA
Index       dd 0        ; define this Index
ARRAY_LENGHT DWORD 0
PTR_ROOM DWORD 0
intro   byte   "press \ in a blank line to exit this loop, while this",0dh,0ah,00hintro1 byte "now, showing what you have typed",0dh,0ah,00h
name1 byte "enter some name: ",00h
error byte "oops, cannot insert this string, don't have free space in array",00h

        .CODE
main    PROC
;array with variable input string

        call    Clrscr ;clear the screen
        mov     edx, offset intro ;present the intro
        call    WriteString ;show intro on screen
include_next:
      mov      esi, offset MyArray
      mov      ecx,256
      mov      ebx,1
      call    dumpmem
        mov     edx, offset name1 ;enter your name
        call    WriteString
      mov ecx,80
      mov  edx,OFFSET stringIn ;the buffer that hold the string
      mov  ecx,MAX            ;buffer size - 1
      call ReadString ;return in eax the number of chars typed
      mov      esi, offset stringIn   ;source
      mov      edi, offset MyArray      ;destin
      cmp      byte ptr stringIn,"\"
      je      ended

have_space:
      add ARRAY_LENGHT,1 ;room for the counter
      add ARRAY_LENGHT,eax ;in eax have the number of chars typed by the user
      cmp ARRAY_LENGHT,ARRAY_SIZE ;the array is full?
      jb include1 ;no, so find next room
      mov edx, offset error ;yes, show error to user
      call    WriteString
      call WaitMsg
      jmp ended ;and go to the end

include1:
      add edi,PTR_ROOM ;moment1 is 0
      mov byte ptr [edi],al ;we store first the counter of typed chars
      inc PTR_ROOM ;and add 1 to ptr_room because counter have 1 byte
      add PTR_ROOM,eax ;and add eax(al) because number or chars user have typed
      inc edi ;next place
      mov cl,al ;the counter goes to cl
again:
      lodsb ;read 1 byte from our buffer
      stosb ;and store in array
      loop again ;and do this cl times
      jmp include_next ;loop again
ended:
        call    Clrscr ;clear the screen
        mov     edx, offset intro1 ;show some intro to user
        call    WriteString
      mov esi, offset MyArray ;esi == ptr to my array
      cmp byte ptr [esi],0 ;is the first byte of array 0? so the user dont have inserted nothing in it, go out
      je endend
again2:
       ;load byte from buffer
      cmp al,0 ;is zero? we get the end of array
      je endend
      mov cl,al ;that byte is a counter
continue_eco:
      lodsb ;read cl times it and show a char in screen
      call WriteChar
      loop continue_eco
      call Crlf
      jmp again2
endend:
call WaitMsg
        exit
main    ENDP

ShowArray       proc
                mov     edi, offset MyArray
                xor     ebx, ebx
    _next:      cmp     ebx, Index
                jne     @F
                ret
        @@:     mov     eax, [edi+ebx]    ; get EAX from the array
                add     ebx, 4            ; point to next dword
                call WriteInt
;            call Crlf
            jmp     _next
            ret
ShowArray       endp

        END     main
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 28, 2011, 12:45:45 PM
cut and paste error for the first error but intro is still undefined. I am guessing it does not want to read the procedure now?
Title: Re: How do you read a string into an array?
Post by: jj2007 on April 28, 2011, 12:54:00 PM
How do you want the assembler to interpret this??

intro   byte   "press \ in a blank line to exit this loop, while this",0dh,0ah,00hintro1 byte "now, showing what you have typed",0dh,0ah,00h
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 28, 2011, 12:56:10 PM
Quote from: jj2007 on April 28, 2011, 12:54:00 PM
How do you want the assembler to interpret this??

intro   byte   "press \ in a blank line to exit this loop, while this",0dh,0ah,00hintro1 byte "now, showing what you have typed",0dh,0ah,00h

sfu error
:)
Title: Re: How do you read a string into an array?
Post by: RuiLoureiro on April 28, 2011, 04:05:06 PM
bcddd214,
            Try this code and say what it does
            (i didnt test it, i havent Irvine32.inc)

            works corretly ? (type ENTER to exit)


TITLE   Strings
        INCLUDE Irvine32.inc

CpyStrArray proto   :DWORD,:DWORD,:DWORD,:DWORD
ShowString  proto   :DWORD,:DWORD

MAXLENGTH   equ 63
MAXLENGTH1  equ MAXLENGTH+1
MAXINDEX2    equ 100


.DATA
        Info1       db "Type your string",13,10, 0
       
        AnyString   db MAXLENGTH1 + 5 dup (?)   
        MyStrArray  db MAXLENGTH1 * MAXINDEX2 dup (?)
        MaxIndex    dd 0

        CRLF1        db 13, 10, 0
.CODE
main        proc

    _next:  call    Clrscr ;clear the screen

            mov     edx, offset Info1
            call    WriteString
            ;
            ; Read the string to AnyString
            ; ----------------------------
      mov     edx, offset AnyString ;the buffer that hold the string
      mov     ecx, MAXLENGTH      ;buffer size - 1
      call    ReadString       ;return in eax the number of chars typed
            ;
            cmp     eax, 0                ; EAX=length
            je      _exit
            ;
            ; Put AnyString into MyStrArray
            ; -----------------------------
            add     MaxIndex, 1
            invoke  CpyStrArray, offset AnyString, eax, offset MyStrArray, MaxIndex

            jmp     _next
;-------------*****------------------
;  Show each string one after another
;-------------*****------------------
    _exit:  call    Clrscr ;clear the screen

            invoke  ShowString, addr MyStrArray, MaxIndex

            call    WaitMsg
            exit
main        endp
;----------------------------
CpyStrArray proc    pSrc:DWORD, lSrc:DWORD, pDst:DWORD, Idx:DWORD
            push    esi
            push    edi

            mov     ecx, Idx
            cmp     ecx, 0
            je      _exit
            ;
            cmp     ecx, MAXINDEX2
            ja      _exit

            mov      edi, pDst           ; point to array
            ;
            mov      eax, MAXLENGTH1
            sub      ecx, 1
            mul      ecx
            add      edi, eax                ; EDI points to MyStrArray[N]
            ;
            mov     esi, pSrc           ; source
            mov     ecx, lSrc           ; length=number of chars
           
            mov     byte ptr [edi + ecx], 0  ; null terminated string           
            ;
            ; copy from last to first
            ; »»»»»»»»»»»»»»»»»»»»»»»
    @@:     sub     ecx, 1
            movzx   eax, byte ptr [esi + ecx]
            mov     byte ptr [edi + ecx], al
            jnz     short @B           
           
    _exit:  pop     edi
            pop     esi
            ret
CpyStrArray endp
;------------------------------
ShowString  proc    pArray:DWORD, IdxMax:DWORD
            push    ebx
            push    esi
            ;
            xor     ebx, ebx                ; index
           
            mov     esi, pArray
            mov     ecx, IdxMax
            ;
            cmp     ecx, 0
            je      _end
            ;
    @@:     mov     eax, MAXLENGTH1
            mul     ebx
            ;
            mov     edx, eax
            add     edx, esi
call    WriteString

            mov     edx, offset CRLF1
            call    WriteString
            ;
            add     ebx, 1                  ; next index
            sub     ecx, 1
            jnz     short @B
           
    _end:   pop     esi
            pop     ebx
            ret
ShowString  endp
        END     main

Title: Re: How do you read a string into an array?
Post by: mineiro on April 28, 2011, 09:07:52 PM
I have installed irvine to help bcddd214, and compiled your code Sr RuiLoureiro and works fine, but need only a bit of modifications because Irvine uses non sensitive.
so, changing all MAXINDEX (uppercase) to MAXINDEX2 resolve this
and changing CRLF to CRLF1 too - Irvine uses the same in a call.
regards.
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 28, 2011, 09:08:50 PM
Quote from: bcddd214 on April 27, 2011, 04:48:49 AM
Quote from: dedndave on April 27, 2011, 04:35:34 AM
one way to do what you want would be to create an array of string like Hutch said
  mbr1 db 256 dup (?)
  mbr2 db 256 dup (?)
  mbr3 db 256 dup (?)
  mbr4 db 256 dup (?)
  mbr5 db 256 dup (?)
  mbr6 db 256 dup (?)

then, instead of trying to push the name entered onto the stack, push the address of the name onto the stack
then, the addresses will pop off in reverse order, as desired

in this case, you do not need an array of pointers
  parr dd mbr1, mbr2, mbr3, mbr4, mbr5, mbr6

I like this "push the address of the name onto the stack
then, the addresses will pop off in reverse order, as desired"
Your pushing me into pointers which was going to be my next question.....   :)
because each string buffer is 256 bytes
it is easy to calculate the address of a particular one by multiplying the index by 256 and adding the address of the first one
(256 being a power of 2 makes the multiplication very simple)

the strings above may be numbered 1 through 6, but those are just names   :P
you may refer to them as 0 through 5
then use that as the index

so, if you want the 4th string (index = 3)
offset mbr1 + 256*3 is the address

You appear to be creating a number of arrays?

What does 'mbr1' represent?
Title: Re: How do you read a string into an array?
Post by: bcddd214 on April 28, 2011, 09:12:07 PM
Quote from: mineiro on April 28, 2011, 09:07:52 PM
I have installed irvine to help bcddd214, and compiled your code Sr RuiLoureiro and works fine, but need only a bit of modifications because Irvine uses non sensitive.
so, changing all MAXINDEX (uppercase) to MAXINDEX2 resolve this
and changing CRLF to CRLF1 too - Irvine uses the same in a call.
regards.

I have a 'MAX' but not a MAXINDEX?
Title: Re: How do you read a string into an array?
Post by: RuiLoureiro on April 28, 2011, 09:39:30 PM
Quote from: mineiro on April 28, 2011, 09:07:52 PM
I have installed irvine to help bcddd214, and compiled your code Sr RuiLoureiro and works fine, but need only a bit of modifications because Irvine uses non sensitive.
so, changing all MAXINDEX (uppercase) to MAXINDEX2 resolve this
and changing CRLF to CRLF1 too - Irvine uses the same in a call.
regards.

mineiro,
           Ok  :U
Title: Re: How do you read a string into an array?
Post by: RuiLoureiro on April 30, 2011, 03:04:30 PM
 mineiro,
          could you compile this ?
          Does this works ?
          Ok, thanks

TITLE   Strings
        INCLUDE Irvine32.inc

ShowStringT proto   :DWORD
ShowStringR proto   :DWORD

MAXLENGTH   equ 63
MAXLENGTH1  equ MAXLENGTH+1
MAX_INDEX   equ 5   ;100

MAX_BUFFER  equ MAXLENGTH1 * MAX_INDEX


.DATA
        Info1       db "Type your string ", 0
        Info2       db " :", 0
       
        Info3       db "Buffer or Table is full",13,10, 0
       
        AnyString   db MAXLENGTH1 + 5 dup (?)
        MyStrBuffer db MAX_BUFFER dup (?)
        MaxIndex    dd 0

                    dd 0
        TablePtr    dd MAX_INDEX dup (?)
       
        PtrBuffer   dd offset MyStrBuffer       ; current buffer pointer
        LastAddress dd 0
       
       _CRLF        db 13, 10, 0
.CODE
main        proc

            mov     eax, offset MyStrBuffer
            add     eax, MAX_BUFFER 
            mov     LastAddress, eax
           
            call    Clrscr ;clear the screen
           
    _next:  call    PrintInfo
            ;
            ; Read the string to AnyString
            ; ----------------------------
      mov     edx, offset AnyString ;the buffer that hold the string
      mov     ecx, MAXLENGTH      ;buffer size - 1
      call    ReadString       ;return in eax the number of chars typed
            ;
            cmp     eax, 0                ; EAX=length
            je      _exit                 ; if eax=0 then exit
            ;
            ; Put AnyString into MyStrBuffer
            ; ------------------------------
            mov     ecx, eax
            call    SetBuffer
            jnc     short _next           ; next string
            ;
            ; Error
            ; -----
            call    WaitMsg

;-------------*****------------------
;  Show each string one after another
;-------------*****------------------
    _exit:  call    Clrscr ;clear the screen

            invoke  ShowStringT, addr TablePtr

            mov     edx, offset _CRLF
            call    WriteString

            invoke  ShowStringR, addr TablePtr

            call    WaitMsg
            exit
main        endp
;------------------------------
PrintInfo   proc

            mov     edx, offset Info1
            call    WriteString

            mov     eax, MaxIndex
            add     eax, 1
            mov     MaxIndex, eax
           
            call    WriteInt
            ;
            mov     edx, offset Info2
            call    WriteString
            ret
PrintInfo   endp
;------------------------------
;       PtrBuffer   - next destination address
;       TablePtr    - table of pointers
;
SetBuffer   proc
            push    esi
            push    edi

            mov     edi, offset TablePtr
            mov     eax, dword ptr [edi - 4]
            add     eax, 1
            cmp     eax, MAX_INDEX
            ja      _exit                           ; there isnt table
            ;
            mov     edx, LastAddress
            sub     edx, PtrBuffer
            cmp     edx, ecx
            jbe     _exit                           ; there isnt buffer

            mov     edx, PtrBuffer                  ; destination
            mov     dword ptr [edi - 4], eax        ; eax=number of pointers
            sub     eax, 1
            mov     dword ptr [edi + eax*4], edx
            ;
            mov     edi, PtrBuffer                  ; destination           
            mov     esi, offset AnyString           ; source
                       
            mov     byte ptr [edi + ecx], 0         ; null terminated string
            mov     edx, ecx                        ; save ECX           
            ;
            ; copy from last to first
            ; »»»»»»»»»»»»»»»»»»»»»»»
    @@:     sub     ecx, 1
            movzx   eax, byte ptr [esi + ecx]
            mov     byte ptr [edi + ecx], al
            jnz     short @B           
            ;
            ; next buffer
            ; -----------
            add     edx, 1
            add     edx, edi
            mov     PtrBuffer, edx                  ; next destination
            clc           
            jmp     _end
           
    _exit:  mov     edx, offset Info3
            call    WriteString
            stc
           
    _end:   pop     edi
            pop     esi
            ret
SetBuffer   endp
;------------------------------
; Show the strings from first to last
; using the table of pointers
;
ShowStringT proc    pTbl:DWORD
            push    ebx
            push    esi
            ;
            xor     ebx, ebx                ; index
           
            mov     esi, pTbl
            mov     ecx, dword ptr [esi - 4]
            cmp     ecx, 0
            je      _end
            ;
    @@:     mov     edx, dword ptr [esi + ebx*4]
call    WriteString

            mov     edx, offset _CRLF
            call    WriteString
            ;
            add     ebx, 1                  ; next index
            sub     ecx, 1
            jnz     short @B
           
    _end:   pop     esi
            pop     ebx
            ret
ShowStringT endp
;------------------------------
; Show the strings from last to first
; using the table of pointers
;
ShowStringR proc    pTbl:DWORD
            push    esi
           
            mov     esi, pTbl
            mov     ecx, dword ptr [esi - 4]

    @@:     cmp     ecx, 0
            je      _end
            ;
            sub     ecx, 1
            mov     edx, dword ptr [esi + ecx*4]
call    WriteString

            mov     edx, offset _CRLF
            call    WriteString
            ;
            jmp     short @B
           
    _end:   pop     esi
            ret
ShowStringR endp
        END     main
       
Title: Re: How do you read a string into an array?
Post by: mineiro on April 30, 2011, 09:33:07 PM
Yes Sr RuilLoureiro, works fine. Show the string in progressive and reversed order. :thumbu
regards.
Title: Re: How do you read a string into an array?
Post by: RuiLoureiro on May 01, 2011, 01:10:36 PM
Quote from: mineiro on April 30, 2011, 09:33:07 PM
Yes Sr RuilLoureiro, works fine. Show the string in progressive and reversed order. :thumbu
regards.
mineiro,
            :thumbu Thank you  :U
       
        Now, i have installed Irvine.inc

        This code sort the strings

TITLE   Strings 3
        INCLUDE Irvine32.inc

ShowStringT proto   :DWORD
ShowStringR proto   :DWORD
StringSort  proto   :DWORD

MAXLENGTH   equ 63
MAXLENGTH1  equ MAXLENGTH+1
MAX_INDEX   equ 100

MAX_BUFFER  equ MAXLENGTH1 * MAX_INDEX


.DATA
        Info1       db "Type your string ", 0
        Info2       db " :", 0
       
        Info3       db "Buffer or Table is full",13,10, 0

        BufString   db MAXLENGTH1 + 5 dup (?)
        AnyString   db MAXLENGTH1 + 5 dup (?)
        MyStrBuffer db MAX_BUFFER dup (?)
        MaxIndex    dd 0

                    dd 0
        TablePtr    dd MAX_INDEX dup (?)
       
        PtrBuffer   dd offset MyStrBuffer       ; current buffer pointer
        LastAddress dd 0
       
       _CRLF        db 13, 10, 0
.CODE
main        proc

            mov     eax, offset MyStrBuffer
            add     eax, MAX_BUFFER 
            mov     LastAddress, eax
           
            call    Clrscr ;clear the screen
           
    _next:  call    PrintInfo
            ;
            ; Read the string to AnyString
            ; ----------------------------
      mov     edx, offset AnyString ;the buffer that hold the string
      mov     ecx, MAXLENGTH      ;buffer size - 1
      call    ReadString       ;return in eax the number of chars typed
            ;
            cmp     eax, 0                ; EAX=length
            je      _exit                 ; if eax=0 then exit
            ;
            ; Put AnyString into MyStrBuffer
            ; ------------------------------
            mov     ecx, eax
            call    SetBuffer
            jnc     short _next           ; next string
            ;
            ; Error
            ; -----
            call    WaitMsg

;-------------*****------------------
;  Show each string one after another
;-------------*****------------------
    _exit:  call    Clrscr ;clear the screen

            invoke  StringSort, addr TablePtr
           
           
            invoke  ShowStringT, addr TablePtr

            mov     edx, offset _CRLF
            call    WriteString

            invoke  ShowStringR, addr TablePtr

            call    WaitMsg
            exit
main        endp
;------------------------------
PrintInfo   proc

            mov     edx, offset Info1
            call    WriteString

            mov     eax, MaxIndex
            add     eax, 1
            mov     MaxIndex, eax
           
            call    WriteInt
            ;
            mov     edx, offset Info2
            call    WriteString
            ret
PrintInfo   endp
;------------------------------
;       PtrBuffer   - next destination address
;       TablePtr    - table of pointers
;
SetBuffer   proc
            push    esi
            push    edi

            mov     edi, offset TablePtr
            mov     eax, dword ptr [edi - 4]
            add     eax, 1
            cmp     eax, MAX_INDEX
            ja      _exit                           ; there isnt table
            ;
            mov     edx, LastAddress
            sub     edx, PtrBuffer
            cmp     edx, ecx
            jbe     _exit                           ; there isnt buffer

            mov     edx, PtrBuffer                  ; destination
            mov     dword ptr [edi - 4], eax        ; eax=number of pointers
            sub     eax, 1
            mov     dword ptr [edi + eax*4], edx
            ;
            mov     edi, PtrBuffer                  ; destination           
            mov     esi, offset AnyString           ; source
                       
            mov     byte ptr [edi + ecx], 0         ; null terminated string
            mov     edx, ecx                        ; save ECX           
            ;
            ; copy from last to first
            ; »»»»»»»»»»»»»»»»»»»»»»»
    @@:     sub     ecx, 1
            movzx   eax, byte ptr [esi + ecx]
            mov     byte ptr [edi + ecx], al
            jnz     short @B           
            ;
            ; next buffer
            ; -----------
            add     edx, 1
            add     edx, edi
            mov     PtrBuffer, edx                  ; next destination
            clc           
            jmp     _end
           
    _exit:  mov     edx, offset Info3
            call    WriteString
            stc
           
    _end:   pop     edi
            pop     esi
            ret
SetBuffer   endp
;------------------------------
; Show the strings from first to last
; using the table of pointers
;
ShowStringT proc    pTbl:DWORD
            push    ebx
            push    esi
            ;
            xor     ebx, ebx                ; index
           
            mov     esi, pTbl
            mov     ecx, dword ptr [esi - 4]
            cmp     ecx, 0
            je      _end
            ;
    @@:     mov     edx, dword ptr [esi + ebx*4]
call    WriteString

            mov     edx, offset _CRLF
            call    WriteString
            ;
            add     ebx, 1                  ; next index
            sub     ecx, 1
            jnz     short @B
           
    _end:   pop     esi
            pop     ebx
            ret
ShowStringT endp
;------------------------------
; Show the strings from last to first
; using the table of pointers
;
ShowStringR proc    pTbl:DWORD
            push    esi
           
            mov     esi, pTbl
            mov     ecx, dword ptr [esi - 4]

    @@:     cmp     ecx, 0
            je      _end
            ;
            sub     ecx, 1
            mov     edx, dword ptr [esi + ecx*4]
call    WriteString

            mov     edx, offset _CRLF
            call    WriteString
            ;
            jmp     short @B
           
    _end:   pop     esi
            ret
ShowStringR endp
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
StringSort  proc    pTbl:DWORD
            push    ebx
            push    esi
            push    edi
           
            mov     esi, pTbl
            mov     ecx, dword ptr [esi - 4]
            cmp     ecx, 1
            jbe     _end

            sub     ecx, 1
            xor     ebx, ebx
   
    _loop1: invoke  Str_copy, [esi + ebx*4], addr AnyString
            invoke  Str_ucase, addr AnyString
            ;
            ; Next string
            ; -----------
            mov     edx, ebx
            ;
    _loop2: add     edx, 1
            cmp     edx, ecx
            ja      short _next
           
            invoke  Str_copy, [esi + edx*4], addr BufString
            invoke  Str_ucase, addr BufString
            ;
            ; compare
            ; -------
            invoke  Str_compare, addr AnyString, addr BufString
            jbe     short _loop2
            ;
            ; change
            ; ------
            mov     eax, dword ptr [esi + ebx*4]           
            mov     edi, dword ptr [esi + edx*4]
           
            mov     dword ptr [esi + ebx*4], edi           
            mov     dword ptr [esi + edx*4], eax
            jmp     _loop1
            ;
    _next:  add     ebx, 1
            cmp     ebx, ecx
            jb      _loop1           

    _end:   pop     edi
            pop     esi
            pop     ebx
            ret
StringSort  endp
;---------------------------------------
        END     main