我需要创建一个过程,生成一个长度为L的随机字符串,包含所有大写字母。在调用该过程时,我需要在EAX中传递L的值,并传递一个指向将保存随机字符串的字节数组的指针。然后,我需要编写一个测试程序,调用您的过程20次,并在控制台窗口中显示字符串。
下面的代码不起作用,返回时出现以下错误:
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
我对汇编语言还很陌生。。。关于我做错了什么以及如何纠正这些错误,有什么想法吗?非常感谢。
;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
-
ENDP
指令没有标签。而且没有错别字。您的指令不起作用,所以下一个PROC
指令在过程中打开嵌套过程,这在MASM中是不合法的。 -
mov arr1[esi],eax
存储4个字节,而不是一个字节(考虑一下当您最后有3个字母并且缓冲区只有10个字节长时会发生什么)。 -
ENDP
只是MASM指令,而不是指令,因此RandomString
代码将在loop
指令之后继续执行某些,无论发生在以下内存中。您可能对ret
指令感兴趣。并检查Display
子程序。 -
RandomString
使用esi
作为输入参数,您可以在其中设置目标缓冲区的地址。然后它执行mov arr1[esi],...
,所以它将执行arr1+arr1
地址计算,很可能导致无效的内存访问(或静默内存覆盖某个地方的,但肯定不在缓冲区中)。如果mov [esi],...
已经包含指向缓冲区的指针,那么它就足够了。 -
Display
使用esi
,但您没有将其设置在call Display
之前,因此它将在esi
中找到RandomString
。并再次进行arr1[esi]
,即arr1+esi
地址计算。 -
"EAX=ASCII值">。。。我非常怀疑这一点,因为ASCII值只需要8位,而您从内存中加载32位。此时的
eax
很可能包含4个字符。但是WriteChar
将只使用eax
的底部8位,因此它将按预期工作,但它仍然是一种错误,表明您对本机CPU数据类型/寄存器的误解/无知。 -
有多个
L1
标签,我认为它们在MASM中是全局的(但也许PROC
会定位它们)。总的来说,如果我告诉你我的代码标签L1
中有什么,它告诉你它的用途是什么?如果我把它重命名为AlienInvasionV4_HandlerOfMultidimensionalTeleportationError:
,即使没有看到代码,你也能猜到它的功能吗?使用像"L1"这样神秘的东西有什么意义? -
CCD_ 28中没有环路。
-
RandomString
将更改ecx
(即使main
中有循环,它也不会按预期工作)。 -
Display
将尝试同时使用eax
值作为输入,但您不会将其设置在call Display
之前。
。。。也许还有一些bug,但我已经厌倦了通读它(我没有windows+irvine lib来实际运行它,所以我所有的笔记都只是通过校对你的源代码并在头脑中运行它…想象一下你也可以自己阅读它,并对每一条指令进行推理,哇!)。。。你应该能够自己找到+修复其中的大部分,不确定你在SO上问的是什么。这将比用错误使用的ENDP
修复少数语法错误更乏味。尽管你的代码对算法的健全性有一点了解,但并不会像你根本不了解CPU那样感到完全无知(除了你错过了寄存器的"超全局"性质,并希望它们在调用时保持其值),更像是缺乏精度和经验。使用ASM,您将需要更高的精度,机器将很乐意执行您向其发出的任何法律指令,而不会对后果发出任何警告。