20 Random Strings containing all capital letters

2019-07-27 01:03发布

I need to create a procedure that generates a random string of length L, containing all capital letters. When calling the procedure, I need to pass the value of L in EAX, and pass a pointer to an array of byte that will hold the random string. Then I need to write a test program that calls your procedure 20 times and displays the strings in the console window.

The code below wont work it comes back with these errors:

Line (33): error A2008: syntax error : main ENDP
Line (35): error A2144: cannot nest procedures
Line (46): error A2008: syntax error : RandomString
Line (48): error A2144: cannot nest procedures
Line (59): warning A6001: no return from procedure
Line (66): fatal error A1010: unmatched block nesting

I am still very new with Assembly Language...Any ideas on what I'm doing wrong and how to fix these errors? Thank you.

;Random Strings.

INCLUDE Irvine32.inc
TAB = 9                       ;ASCII code for Tab
strLen=10                     ;length of the string

.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO, dwExitCode:DWORD

.data
str1 BYTE"The 20 random strings are:", 0
arr1 BYTE strLen DUP(?)

.code
main PROC
     mov ed x, OFFSET str1         ;"The c20 random strings are:"
     call WriteString              ;Writes string
     call Crlf                     ;Writes an end-of-line sequence to the console window.
     mov ecx,20                    ;Create 20 strings

 L1: mov esi,OFFSET arr1           ;ESI: array address
     mov eax,strLen                ;EAX: string length
     call RandomString             ;generates the random string
     call Display
     mov al,TAB
     call WriteChar                ;leaves a tab space
     exit
main ENDP

     RandomString PROC USES eax esi
     mov ecx,eax                   ;ECX = string length

L1:  mov eax, 26
     call RandomRange
     add eax,65                    ;EAX gets ASCII value of a capital letter
     mov arr1[esi],eax
     inc esi

     loop L1

     RandomString EXDP

     Display PROC USES eax esi     ;Displays the generated random string

     mov ecx,eax                   ;ECX=string length

L1:  mov eax, arr1[esi]            ;EAX = ASCII value
     call WriteChar                ;writes the letter

     inc esi

     loop L1

     Display ENDP


        call dumpregs

        INVOKE ExitProcess,0

END main

1条回答
在下西门庆
2楼-- · 2019-07-27 01:58
  • The ENDP directive goes without label. And without typos. Yours don't work, so the next PROC directive opens nested procedure inside procedure, that's not legal in MASM.

  • mov arr1[esi],eax stores 4 bytes, not one (consider what happens when you are at last 3 letters and buffer is only 10 bytes long).

  • The ENDP is only MASM directive, not instruction, so your RandomString code will continue executing something after the loop instruction, whatever happens to be in the following memory. You probably may be interested into ret instruction. And check also Display subroutine.

  • RandomString uses esi as input argument, where you set the address of target buffer. Then it does mov arr1[esi],..., so it will do arr1+arr1 address calculation, resulting very likely into invalid memory access (or silent memory overwrite somewhere, but definitely not in your buffer). mov [esi],... is enough, if it already contains pointer to buffer.

  • Display uses esi, but you don't set it ahead of call Display, so it will find in esi whatever the RandomString left there. And it does again arr1[esi], i.e. arr1+esi address calculation.

  • "EAX = ASCII value" ... I would highly doubt that, as ASCII values need only 8 bits, and you load 32 bits from memory. The eax at that point will very likely contain 4 characters. But WriteChar will use only the bottom 8 bits of eax, so it will work as expected, but it's still sort of bug, showing your misunderstanding/ignorance of native CPU data types/registers.

  • there are multiple L1 labels, I thought they are global in MASM (but maybe PROC will localize them). Overall if will tell you I have in my code label L1, what does it say to you about what is it used for? How about if I renamed it to AlienInvasionV4_HandlerOfMultidimensionalTeleportationError:, can you guess anything about its function even without seeing the code? What the point in using something cryptic like "L1"?

  • there's no loop in main.

  • RandomString will change ecx (even if there would be loop in main, it will not work as expected).

  • Display will try to use also eax value as input, but you don't set it ahead of call Display.

... maybe some more bugs, but I got tired of reading through it (I don't have windows+irvine lib to actually run it, so all my notes are just by proofreading your source and running it in head... imagine you could read it after yourself too and reason about each instruction, whoa!) ... you should have been able to find+fix most of these on your own, not sure what you are asking here on SO. It will get lot more tedious than fixing few syntax errors with wrongly used ENDP. Although your code has glimpse of algorithmic sanity, doesn't feel completely clueless like you don't understand CPU at all (except you missed the "super global" nature of registers and expect them to keep their values over calls), more like lack of precision and experience. You will need lot more precision with ASM, the machine will happily execute any legal instruction you throw at it, without any warning about consequences.

查看更多
登录 后发表回答