Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

array of strings 2

Status
Not open for further replies.

mgl70

Programmer
Sep 10, 2003
105
US
hi
I am using the book "assembly language for intel based computers"(MASM) new version.
I writing a program in 32-bit.
I have a question on this.
My program reads a string(user input) every time store it in an array. and display that array end of the program. how to declare that string array and store those strings in that array and display that array at the end of the program.
The program must use a procedure for this

how to do this.If any body knows this help me.
thanks.
 
I'm not entirely sure what you want to do, but I think the best way to do it is by using the DOS interrupts. I have written the code to take in just one string output and display it, but the rest you will have to fill in yourself (for more than one string, you will need some kind of loop, and a larger buffer). Here is the code:
Code:
assume cs:code

code segment
  org 100h

program:
  jmp start

; This is the data area.
  message1 db 'Enter string >$'  ; Prompt message
  message2 db 0dh,0ah,'$'        ; New line (!)
  buffer   db 20		 ; Size of buffer here
	   db 100 dup('$')       ; Fill with '$'

; Actual code starts here
start:
  ; Set up segment registers
  mov ax,cs
  mov ds,ax
  mov es,ax

  ; Output prompt
  mov ah,09h
  lea dx,message1
  int 21h

  ; Get input into buffer
  mov ah,0ah
  lea dx,buffer
  int 21h

  ; Output message
  mov ah,09h
  lea dx,message2
  int 21h
  mov ah,09h
  lea dx,buffer
  add dx,02h     ; Don't want size of buffer...
  int 21h

  ; Terminate program interrupt
  mov ax,4c00h
  int 21h
  ret

code ends
end program
Hope that is useful. :)


The mind is like a parachute - it works better when open...
 
hi, adholioshake

i am new in ASM, feel ?? when read this:

add dx,02h ; Don't want size of buffer...

why? i tried to remark this and got 2 bytes of funny code in front of the buffer.. from where this 2 extra code came from?

thankx.
 
When you called int 21h function 0ah, Buffered Input, the first byte of the buffer contains the maximum number of characters expected as input.

The second byte contains the actual number of characters received by DOS, not including the carriage return.

When you print out the buffer using Int 21h function 09h, Output character string, these two bytes are not required as they hold numbers (byte counts), not ascii characters as such.

Therefore the program adds two to the buffer address in dx to avoid printing out garbage characters.

By commenting out the add dx,02h line, you allowed the program to print out the two numbers as ascii characters, which may or may not be interesting, but is probably not very useful.

rgds
Zeit.
 
got it!
i try to check those 2 codes and found that 1st code was 20 and 2nd code was the number of bytes that i had enter.

thnkx zeitghost

1 more thing is:

buffer db 20 ; Size of buffer here
db 100 dup('$') ; Fill with '$'


why put so many '$' in the buffer?? seems that we need only 20 chars from input. i checked the compiled .COM and found lot of $$$$$$ in it. this will make that .com bigger in size, rite??
 
The db 100 dup('$') is used to create 100 bytes containing the $ character.

This is used as the string terminator character in int 21h, function 09h, Output character string.

In other words, by having a buffer with 100 $ characters in it, you don't have to terminate your input string with a $ character before printing the string out.

It's a cheat, because it will only work once, which is ok for a simple demonstration program like the one you included above.

Otherwise, you'd do something like this:

lea dx,buffer ;get buffer address
inc dx ;point to byte count
sub ah,ah ;clear ah
mov al,[dx] ;get byte count
inc dx ;to start of your input string
add dx,ax ;add the string len
inc dx ;plus one so past the end
mov al,'$'
mov [dx],al ;insert trailing '$'

mov ah,09h ;and print it out.
lea dx,buffer
add dx,2
int 21h

I haven't assembled this and it's a while since I used 8086 assembler, so take care!

rgds
Zeit.
 
Well, I said it had been a while!

You can't use dx as a pointer register.

This is a corrected version.

Interestingly enough, the extremely ancient version of MASM that I used got all confused by the assume command, so I had to change it as shown.

assume cs:code,ds:code,ss:code,es:code ;for a COM file

code segment
org 100h

program:
jmp start

; This is the data area.
message1 db 'Enter string >$' ; Prompt message
message2 db 0dh,0ah,'$' ; New line (!)
buffer db 20 ; Size of buffer here
db 100 dup('$') ; Fill with '$'

; Actual code starts here
start:
; Set up segment registers
mov ax,cs
mov ds,ax
mov es,ax

; Output prompt
mov ah,09h
lea dx,message1
int 21h

; Get input into buffer
mov ah,0ah
lea dx,buffer
int 21h

; Output message
mov ah,09h
lea dx,message2
int 21h

mov ah,09h
lea dx,buffer
add dx,02h ; Don't want size of buffer...
int 21h

lea bx,buffer ;get buffer address
inc bx ;point to byte count
sub ah,ah ;clear ah
mov al,[bx] ;get byte count
inc bx ;to start of your input string
add bx,ax ;add the string len

mov al,'#' ;you would put a $ here, but I use a #
;as an illustration.

mov [bx],al ;insert trailing '$'


mov ah,09h ;and print it out.
lea dx,buffer
add dx,2
int 21h

; Terminate program interrupt
mov ax,4c00h
int 21h
ret

code ends
end program

Hope this helps.

rgds
Zeit.
 
haha!! CLEAR now! :)

i yet felt funny why got [dx] as pointer bfore, but now clear. Thnkx Zeit.

i'll take note on that. Thnkx again Zeit.
 
Another improvement to the program would be to dynamically allocate the buffer for the characters in memory not in the program, as this would get rid of the $$$'s in the binary, but I didn't want to do that because:
1) It was only meant to be a sample program, you can adapt it to do that.
2) If you are not careful you can get rid of something really important already in memory.
3) Its a lot more harder to do.
4) The program is already small enough, so it can afford to have a large array.

I thought I commented out my program enough - I don't usually write lots of comments in my programs. Sorry.


The mind is like a parachute - it works better when open...
 
Hi adholioshake!

At my advanced age, I find that lots of comments help me to remember what I was trying to do when I wrote the code!

Your example was very good & concise in my opinion, and did the job asked of it.

What I found interesting was the reaction of my ancient copy of MASM to the assume statement.

Before I added ds,es, and ss to it, the code generated was decidedly weird, and the pc crashed in flames.

rgds
Zeit.
 
hi adholioshake, zeit,

i am new in ASM. i am learning.

my learning way is READ MORE AND ASK MORE TO GET THE ANSWER.

ofcoz i will ask the question that is in my range of knowledge. this will improve myself. i used this method to learn my ACAD3D and i get it done. now i even can draw the world cup football. :)

ASM is a new chapter for me. i will use the same way to learn it, keep on reading and asking more question that i blur and hope that i will learn more. if i said anything wrong, please forgive me.

To those who can help me or try to help me, i just can say THANK YOU.




---->ASM fresher need help!<----

With kind regards.
syskplim@streamyx.com
 
syskplim,
READ MORE AND ASK MORE TO GET THE ANSWER.

There is nothing wrong to ask more, as long as you don't ask a complete full program. So you don't have to apology :)

Regards

-- AirCon --
 
i am afraid that i had said something wrong and made people unhappy. actually adholioshake's sample at above led me to learn something. he told me that there are many ways to assemble. we can do in simple way rather than write in the actual way. b4 that i really don't understand why he put so many &quot;$$$&quot; in the sample, i tried to check that compiled file and noticed that there were so many &quot;$$$&quot; in the .COM.
thats why i asked and Zeit figured it out for me. he told me the other way to write that part.

Actually, i learnt many things from that sample.

1. why need to skip 2 bytes in buffer
2. how to put '$$$$$' to terminate the buffer and
3. how to find out the length of the buffer and put a '$' at the end of it.

i always look around in this forum and read, if i faced something that i don't understand, i need to ask to make myself clear. i feel sorry if my questions hurt someone. as i said, ---->ASM fresher need help!<----, if a litter boy faced infront of me asked me that 'hi, why u so fat?', i don't think that i ve to kick his ass, rite? he is a fresher too.

post the whole program and ask someone to check is not my learning method. i will never do that.

i join masmforum too. sometime i can get different answers from different people.



---->ASM fresher need help!<----

With kind regards.
syskplim@streamyx.com
 
I don't think you made anyone unhappy syskplim.

I learned a lot from this too!

Mostly that I've forgotten quite a lot since last I programmed an 80x86 in assembler!

Even had to look up the commands for debug in the dos manual, and I thought they were engraved on my soul!

And I discovered that my old 286 didn't work because the cmos battery holder had split, so it forgot what kind of hard disk it had etc.

rgds
Zeit.
 
Sometimes when I write posts they sound report like and it makes me sound like a grumpy sod. This is why I write code more than english, because that's ultimately what you want to learn - and I learn from writing the programs 90% of the time too. :)


The mind is like a parachute - it works better when open...
 

thanks for your replies.
I did not go up to lea and 21h.
I am using MASM615.
My code is
.data
myarray BYTE 100 DUP(?) ; 100 is like max strings
.code
mov edx,OFFSET myarray
mov esi,OFFSET myarray

Now I have to take user input strings every time and store it in that array.For this I need to add null terminated character also at the end of the each string. At the end of the program I need to print all the strings.
Please explain..!
Thanks
 
There are a few things to point out here:

1) The array should consist of a number of elements(strings in this case), as that is what defines the array.
2) These elements should each be the same size, because it makes life much easier.
3) The total size of the array should be equal (or greater than) the number of elements multiplied by the size of an element.

That might seem trivial, but its best to point all that out before attempting to program the thing.

The next thing to point out is that input and output of the array elements might not be as simple as the program I wrote earlier - in fact it requires some string manipulation.
The way I have done it is to keep the array separate from any i/o, and use a buffer for all the i/o. This just means relevent data has to be copied from/to the buffer.

I think thats enough pre-code talk...
The code is as follows (I commented out a bit more, but if you don't understand, post again.)
Code:
; A program to demonstrate array use

;===================================

; useful values :)
element_size    equ 012h
element_number  equ 005h
array_size      equ 060h  ; >= (element_size * element_number)


.model 386        ; tell masm the model we use
                  ; (my MASM complains if you dont
                  ; include a model...)

;=================================
.stack
  db 100h dup(?)  ; put a stack here to stop
                  ; MASM complaining...

;=================================
.data
  ; Needed for better text i/o
  message  db 'Enter string >$'  ; Prompt message
  newline  db 0dh,0ah,'$'        ; New line (!)

  ; Buffer used for input and output
  buffer   db 11h          ; Max buffer size (element_size - 1)
           db  ?           ; Actual buffer size
           db 11h dup(?)   ; Make buffer

  ; Array to hold strings:
  array    db array_size dup('*')
           db '$'

  ; used for accessing different elements of the array
  array_position dw ?


;=================================
.code
  ; Set up segment registers
  mov ax,@data
  mov ds,ax
  mov es,ax

;====================================================
; This first loop gets input from the user and  
; converts the result from the interrupt into the
; 0-terminated string stored in the array.
;====================================================
  lea di,array
  mov [array_position],di ; save array position

  mov cx,element_number
input_loop:
  push cx        ; save value for end of loop

  ; Output prompt
  mov ah,09h
  lea dx,newline ; Leave a line before prompt
  int 21h

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

  ; Get input into buffer
  mov ah,0ah
  lea dx,buffer
  int 21h

  ; transfer input from buffer into array
  lea si,buffer
  inc si
  sub cx,cx
  mov cl,[si]    ; Get size of string
  inc si

string_transfer:
  lodsb         ; get byte from buffer into al
  mov [di],al   ; move byte from al into array
  inc di        ; update string position
  loop string_transfer

  mov al,00h
  mov [di],al

  pop cx                ; restore value...

  mov di,[array_position]
  add di,element_size   ; ...update array position...
  mov [array_position],di

  loop input_loop       ; ...and loop!



;====================================================
; This next loop converts all the strings in the 
; array into a form in the buffer for outputing
; to the screen.
;====================================================
  lea si,array
  mov [array_position],si ; save array position 

  mov cx,element_number
output_loop:
  push cx          ; save value for end of loop

; transfer input from array into buffer
  lea di,buffer
string_transfer2:
  lodsb            ; get byte from string into al
  or al,al         ; check if it is zero (ie end string)
  jz end_string_transfer2
  mov [di],al      ; move byte from al into buffer
  inc di           ; update string position
  jmp string_transfer2

end_string_transfer2:
  mov al,'$'       ; required to show end of string
  mov [di],al

  mov ah,09h
  lea dx,newline   ; Print on next line
  int 21h

  lea dx,buffer    ; Print contents of buffer
  int 21h

  pop cx                 ; restore cx value...

  mov si,[array_position]
  add si,element_size    ; ...update array position...
  mov [array_position],si

  loop output_loop       ; ...and loop!
;=================================


  mov ah,09h
  lea dx,newline   ; Next line...
  int 21h

  ; I have included this here to show you what
  ; the array looks like in memory.
  ; You will understand when you run the program
  ; :)
  mov ah,09h
  lea dx,array
  int 21h
  
  mov ah,09h
  lea dx,newline   ; Next line...
  int 21h

  ; Terminate program
  mov ax,4c00h
  int 21h

end
That looks like a lot, but its not too bad. I suggest copying it and running the program, then look at how the code works. It still could be improved in many ways, but that is something perhaps you could try.
Essentially, the program is just a derivative of the one I wrote earlier, it just uses a bit more class with the string handling for i/o. :)

Adonai



The mind is like a parachute - it works better when open...
 
adholioshake is quite right to keep all the records the same size so as to make things a lot simpler. If you have very varied sizes of records and need to be more memory efficient then you have to start messing about with things like linked lists and trees. The principle there is that you don't know how long the record is, so you store the string (and any other data you want), together with the address of the next record (if things aren't to big, you just store the offset, otherwise a full pointer). The downside is that if I ask for the 7th record, you have to read through addresses to find it (read the first address, look it up, read the second, look that up... to the seventh). Whereas with fixed record sizes you simply jump directly to start + (n times record-size).
But this is a thing to do later after you've got the fixed-length version working.
 
adholioshake,

This is why I write code more than english, because that's ultimately what you want to learn

I am more than happy to see you are willing to spend your time to write code for others. I also learned something here. At least to bring back my old days :)

You deserve a star for your effort and your time. And so to Zeitghost

[thumbsup2]
Regards

-- AirCon --
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top