Reputation: 11
I am trying to add strings to an array for later printing from the array and this is what I have. What am I missing?
INCLUDE Irvine32.inc
.data
array dword 20 dup (0)
str1 byte 20 dup (0)
temp dword ?
n dword ?
count dword 0
mes1 db "press 1 to add an element, 2 to print, 3 to quit ", 0
.code
main PROC
start:
lea edx, mes1
call writestring
call readdec
cmp eax, 1
je add1
cmp eax, 2
je print2
cmp eax, 3
je stop
add1:
call readin
jmp done
print2:
call print
jmp done
done:
jmp start
stop:
exit
main ENDP
readin proc
lea edx, str1
mov ecx, sizeof str1
call readstring
mov ebx, count
mov eax, [array]
mov temp, eax
add temp, ebx
lea esi, temp
mov ebx, [str1]
mov [esi], ebx
readin endp
print proc
mov esi, 0
mov ecx, n
@@do:
mov eax, Array[esi]
call writedec
call crlf
add esi, 4
@@while: loop @@do
ret
print endp
END main
Upvotes: 1
Views: 9121
Reputation: 14409
The simplest solution is to create an array of bytes that contains null-terminated strings in a row. This is not really an "array of strings". Ingredients: A big buffer and a pointer that points to the end of the valid part of that buffer.
INCLUDE Irvine32.inc
.DATA
arrayptr DWORD OFFSET array
array BYTE 4096 DUP (?)
mes1 BYTE 10, "press 1 to add an element, 2 to print, 3 to quit ", 0
.CODE
readin PROC
mov edx, arrayptr ; Argument for ReadString: Pointer to memory
mov ecx, 10 ; Argument for ReadString: maximal number of chars
call ReadString ; Doesn't change EDX
test eax, eax ; EAX == 0 (got no string)
jz done ; Yes: don't store a new arrayptr
lea edx, [edx+eax+1] ; EDX += EAX + 1
mov arrayptr, edx ; New pointer, points to the byte where the next string should begin
done:
ret
readin ENDP
print PROC
lea edx, array ; Points to the first string
L1:
cmp edx, arrayptr ; Does it point beyond the strings?
jae done ; Yes -> break
call WriteString ; Doesn't change EDX
call Crlf ; Doesn't change EDX
scan_for_null:
inc edx
cmp BYTE PTR [edx], 0 ; Terminating null?
jne scan_for_null ; no -> next character
inc edx ; Pointer to next string
jmp L1
done:
ret
print ENDP
main PROC
start:
lea edx, mes1
call WriteString
call ReadDec
cmp eax, 1
je add1
cmp eax, 2
je print2
cmp eax, 3
je stop
jmp next ; This was missing in the OP
add1:
call readin
jmp next ; Just a better name than in the OP
print2:
call print
jmp next ; Just a better name than in the OP
next: ; Just a better name than in the OP
jmp start
stop:
exit
main ENDP
END main
The elements of an array all have typically the same size (bytes in the example above). So the position of an element can be indexed and easily calculated with that index. It's not as easy to determine the position of a certain string inside of an array of bytes. The array must be scanned from the beginning for string-terminating zeros (take a look at the block scan_for_null
). An "array of strings" is actually an array of pointers to strings:
INCLUDE Irvine32.inc
.DATA
bufptr DWORD OFFSET buf ; Pointer to the beginning of free buffer
buf BYTE 4096 DUP (?) ; Space for 4096 characters
array DWORD 20 DUP (?) ; Space for 20 pointers
arrayindex DWORD 0 ; Index of the next free pointer in array
mes1 BYTE 10, "press 1 to add an element, 2 to print, 3 to quit ", 0
.CODE
readin PROC
mov edx, bufptr ; Argument for ReadString: Pointer to memory
mov ecx, 10 ; Argument for ReadString: maximal number of chars
call ReadString ; Doesn't change EDX
test eax, eax ; EAX == 0 (got no string)
jz done ; Yes: don't change bufptr
mov esi, arrayindex
mov [array + esi * 4], edx ; Store the actual bufptr
inc arrayindex
lea edx, [edx+eax+1] ; EDX += EAX + 1 (new bufptr)
mov bufptr, edx ; New pointer, points to the byte where the next string should begin
done:
ret
readin ENDP
print PROC
xor esi, esi ; First index
L1:
cmp esi, arrayindex ; Beyond last index?
jae done ; Yes -> break
mov edx, [array + esi * 4] ; Argument for WriteString: pointer to a null-terminated string
call WriteString
call Crlf
inc esi
jmp L1
done:
ret
print ENDP
main PROC
start:
lea edx, mes1
call WriteString
call ReadDec
cmp eax, 1
je add1
cmp eax, 2
je print2
cmp eax, 3
je stop
jmp next
add1:
call readin
jmp next
print2:
call print
jmp next
next:
jmp start
stop:
exit
main ENDP
END main
Upvotes: 1