我需要创建一个生成长度为L的随机字符串的过程,其中包含所有大写字母。在调用过程时,我需要在EAX中传递L的值,并将指针传递给将保存随机字符串的byte数组。然后我需要编写一个测试程序,调用你的程序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
答案 0 :(得分:2)
ENDP
指令没有标签。没有错别字。你的工作不起作用,所以下一个PROC
指令在程序中打开嵌套程序,这在MASM中是不合法的。
mov arr1[esi],eax
存储4个字节,而不是一个(考虑到最后3个字母时发生的情况,缓冲区只有10个字节)。
ENDP
只是MASM指令,而不是指令,因此RandomString
代码将在loop
指令后继续执行某些,无论发生什么在以下记忆中。您可能对ret
instruction感兴趣。并检查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”这样神秘的东西有什么意义?
main
中没有循环。
RandomString
将更改ecx
(即使main
中存在循环,它也无法按预期工作)。
Display
会尝试同时使用eax
值作为输入,但不要将其设置在call Display
之前。
...也许还有一些错误,但我厌倦了阅读它(我没有windows + irvine lib来实际运行它,所以我的所有笔记都只是通过校对你的源代码并在头脑中运行它。 ..想象一下,你也可以自己阅读并理解每一条指令,哇!)...你应该能够自己找到+修复大部分这些,不知道你在这里问的是什么。与使用错误使用的ENDP
修复一些语法错误相比,它会更加更多乏味。虽然你的代码已经看到了算法的健全性,但是你并不觉得完全无法理解CPU(除了你错过了寄存器的“超全局”特性并希望它们保持其值超过调用),更像缺乏精确和经验。使用ASM需要更高的精确度,机器将很乐意执行您向其投掷的任何法律指令,而不会对后果发出任何警告。