问题
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:
The
ENDPdirective goes without label. And without typos. Yours don't work, so the nextPROCdirective opens nested procedure inside procedure, that's not legal in MASM.mov arr1[esi],eaxstores 4 bytes, not one (consider what happens when you are at last 3 letters and buffer is only 10 bytes long).The
ENDPis only MASM directive, not instruction, so yourRandomStringcode will continue executing something after theloopinstruction, whatever happens to be in the following memory. You probably may be interested into ret instruction. And check alsoDisplaysubroutine.RandomStringusesesias input argument, where you set the address of target buffer. Then it doesmov arr1[esi],..., so it will doarr1+arr1address 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.Displayusesesi, but you don't set it ahead ofcall Display, so it will find inesiwhatever theRandomStringleft there. And it does againarr1[esi], i.e.arr1+esiaddress calculation."EAX = ASCII value" ... I would highly doubt that, as ASCII values need only 8 bits, and you load 32 bits from memory. The
eaxat that point will very likely contain 4 characters. ButWriteCharwill use only the bottom 8 bits ofeax, 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
L1labels, I thought they are global in MASM (but maybePROCwill localize them). Overall if will tell you I have in my code labelL1, what does it say to you about what is it used for? How about if I renamed it toAlienInvasionV4_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.RandomStringwill changeecx(even if there would be loop inmain, it will not work as expected).Displaywill try to use alsoeaxvalue as input, but you don't set it ahead ofcall 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.
来源:https://stackoverflow.com/questions/47027422/20-random-strings-containing-all-capital-letters