I'm trying to create a procedure that generates a random string of length L, containing all capital letters. This procedure receives the length of the string (L) in EAX, and the pointer to a byte array in ESI where the random string will be saved. Returns the pointer to a byte array in ESI held the random string.
;.386
;.model flat,stdcall
;.stack 4096
;ExitProcess PROTO, dwExitCode:DWORD
INCLUDE Irvine32.inc
.data
;bArray BYTE 100 DUP(0), 0
bArray BYTE ?
count DWORD ?
ranNum DWORD ?
.code
main proc
call Clrscr
mov esi, OFFSET bArray
call Randomize
mov ecx, 20
L1:
;call Random32
mov count, ecx
mov eax, 100
call RandomRange
inc eax
mov ranNum, eax
call CreateRandomString
loop L1
invoke ExitProcess,0
main endp
CreateRandomString PROC
; Receives: Length of the string (L) in EAX, the pointer
; to a byte array in ESI where the random string will be saved
; Returns: Pointer to a byte array in ESI held the random string
;-----------------------------------------------------
mov ecx, ranNum
L2:
mov eax, 26
call RandomRange
add eax, 65
mov[esi], eax
call WriteChar
loop L2
mov ecx, count
call Crlf
ret
CreateRandomString ENDP
end main
This is my code so far and it generates the random length strings, but the loop is infinite when I only want it to iterate 20 times. I know that the 20 I put in ecx gets lost but I'm not sure where in the code that happens and what I should do to change it. I'm thinking something to do with push and pop but I'm still shaky and confused on that concept. Thank you in advance!
Is it intentional that you are storing all of the string's characters on top of each other?
With
bArray BYTE ?andmov esi, OFFSET bArray, later followed by not incrementing ESI in the CreateRandomString procedure, this is exactly what will happen.Why you get an infinite loop
With bArray defined as a mere byte, you should not be writing a full dword to it, as in
mov [esi], eaxbut rather writemov [esi], al. You have effectively destroyed the value 20 that you stored in the count variable (that you introduced as a convoluted way to preserve ECX). As a result, theloopinstruction in the main L1 loop will always be acting upon ECX=0, looping back indefinitely!If you want to use ECX a second time in your CreateRandomString procedure, then simply preserve it on the stack:
As others have suggested, preserving and restoring ECX in the CreateRandomString procedure would not be necessary if you would use another counting register in the main L1 loop. And as a bonus, you will have avoided using the slow
loopinstruction: